#if defined(ARCTIC)
#if (FEATURE_MODE == 0)
/**
 @file sys_at_dot1ae.c

 @date 2020-10-30

 @version v1.0

 The file contains at DOT1AE APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_nexthop.h"
#include "sys_usw_common.h"
#include "sys_at_dot1ae.h"
#include "sys_usw_dot1ae.h"
#include "drv_api.h"
#include "sys_usw_scl_api.h"
#include "sys_usw_ftm.h"
#include "sys_usw_port.h"
#include "sys_usw_dma.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_xdata_api.h"


extern int32 _sys_tmm_dot1ae_lkup_sec_sa_idx(uint8 lchip,uint8 an,void* p_sec_chan);
extern int32 _sys_tmm_dot1ae_get_chan_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data);
extern sys_dot1ae_chan_t*  _sys_usw_dot1ae_chan_lookup(uint8 lchip,uint32 chan_id);

#define SYS_AT_DOT1AE_STATS_NUM 6
#define SYS_AT_DOT1AE_CAM_STEP 2
#define SYS_AT_DOT1AE_MASKBMP_EMPTY 0
#define SYS_AT_DOT1AE_MASKBMP_MSB 10

#define SYS_DOT1AE_GET_DP_ID(lchip,gport_tmp,dp_id) \
{  \
    sys_usw_dmps_port_info_t dmps_port_info = {0};  \
    dmps_port_info.gport = gport_tmp;  \
    CTC_ERROR_DUMP(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &dp_id));  \
}
#define SYS_DOT1AE_GET_DP_BMP(lchip,gport,dp_bmp) \
{  \
   uint32 dp_id=0; \
   SYS_DOT1AE_GET_DP_ID(lchip,gport,dp_id); \
   CTC_BIT_SET(dp_bmp, dp_id);\
}


#define __INTERNAL_FUNC__


STATIC int32
_sys_at_dot1ae_get_chan_by_idx_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    sys_dot1ae_chan_t* p_tmp_sys_chan = NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    uint8 dp_id = 0;
    p_tmp_sys_chan = (sys_dot1ae_chan_t*)traversal_data->data;
    dp_id = traversal_data->value2;

    if ((CTC_SLISTCOUNT(p_sys_chan->bind_mem_list)||(p_sys_chan->binded))
        && (p_sys_chan->dir == p_tmp_sys_chan->dir)
    && (CTC_IS_BIT_SET(p_sys_chan->dp_bmp, dp_id))
    && (p_sys_chan->sc_index[dp_id] == p_tmp_sys_chan->sc_index[dp_id]))
    {
        sal_memcpy(p_tmp_sys_chan,p_sys_chan,sizeof(sys_dot1ae_chan_t));
        traversal_data->value3 = 1;
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_at_dot1ae_map_chanid_portid(uint8 lchip, uint8 dir, uint8 dp_id, uint32 sub_chan_id, uint32 *dest_port)
{
    uint32 cmd = 0;
    ds_t chanToPort;

    if(0 == SDK_WORK_PLATFORM)
    {
        if (dir == CTC_DOT1AE_SC_DIR_RX)
        {
            cmd = DRV_IOR(DsNetRxChanToPortMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &chanToPort));
            *dest_port = GetDsNetRxChanToPortMap(V, portId_f, &chanToPort);
        }
        else
        {
            cmd = DRV_IOR(EpeScheduleChanToPortRa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &chanToPort));
            *dest_port = GetEpeScheduleChanToPortRa(V, physicalPortId_f, &chanToPort);
        }
    }
    else
    {
        *dest_port = sub_chan_id;
    }

    return CTC_E_NONE;
}

int32
_sys_at_dot1ae_update_sec_chan_an_en(uint8 lchip,sys_dot1ae_chan_t* p_sys_sec_chan, uint32 an_bitmap)
{
    uint8 an = 0;
    int32 idx =0;
    uint32 secYId = 0;
    uint32 cmd =0;
    uint32 value =0;
    uint32 key_idx=0;
    ds_t ds;

    p_sys_sec_chan->an_en = an_bitmap&0xF;
    if (p_sys_sec_chan->binded)
    {
        for (an = 0; an < MCHIP_CAP(SYS_CAP_DOT1AE_AN_NUM); an++)
        {
           SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            if (CTC_IS_BIT_SET(p_sys_sec_chan->an_valid, an) && (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX))
            {
                idx = _sys_tmm_dot1ae_lkup_sec_sa_idx(lchip, an, p_sys_sec_chan);
                if (idx == CTC_E_NOT_EXIST)
                {
                    return idx;
                }
                value = CTC_IS_BIT_SET(an_bitmap, an);
                key_idx = (p_sys_sec_chan->sc_index[dp_idx] << 1) + (idx & 0x1);
                cmd = DRV_IOR(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecDecryptSa(V, enableReceive_f, &ds, value);
                cmd = DRV_IOW(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));

            }

            if (!CTC_IS_BIT_SET(an_bitmap, an)
                && (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX))
            {
                if(an_bitmap != 0)
                {
                    continue;
                }
                
            }
            if (CTC_IS_BIT_SET(p_sys_sec_chan->an_valid, an) && (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX))
            {
                idx = _sys_tmm_dot1ae_lkup_sec_sa_idx(lchip, an, p_sys_sec_chan);
                secYId = sys_at_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
                if (idx == CTC_E_NOT_EXIST)
                {
                    return idx;
                }
                cmd = DRV_IOR(DsXSecTxScStatus0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_sec_chan->sc_index[dp_idx], DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecTxScStatus0(V, encodingSa_f, &ds, idx? 1 : 0);
                cmd = DRV_IOW(DsXSecTxScStatus0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_sec_chan->sc_index[dp_idx], DRV_CMD_DP_EN(cmd, dp_idx), &ds));

                value = an_bitmap? 1 : 0;
                cmd = DRV_IOR(DsXSecEncryptSecYPre_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecEncryptSecYPre(V, protectFrames_f, &ds, value);
                cmd = DRV_IOW(DsXSecEncryptSecYPre_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            }
            SYS_DOT1AE_FOREACH_DP_END
        }
    }
    return CTC_E_NONE;
}

int32
sys_at_dot1ae_reset_sec_chan_cfg(uint8 lchip, void* sc_info)
{
    uint32 cmd = 0;
    uint32 value[2] = {0};
    uint16  key_index   = 0;
    uint32 sc_index =0;
    uint8 loop = 0;
    uint8 dp_id =0;
    uint8 sci_hw[8] =   {0};
    ds_t ds;
    sys_dot1ae_chan_t* p_sc_info = (sys_dot1ae_chan_t*)sc_info;
    dp_id =  p_sc_info->dp_id;

    sal_memset(&ds, 0, sizeof(ds));
    for (loop = 0; loop < MCHIP_CAP(SYS_CAP_DOT1AE_AN_NUM); loop++)
    {
        key_index = (p_sc_info->sc_index[dp_id] << 1) + (loop & 0x1);

        /*next pn/windown size*/
        if (p_sc_info->dir == CTC_DOT1AE_SC_DIR_TX)
        {
            value[0] = 1;
            cmd = DRV_IOW(DsXSecEncryptSaStatus_t, DsXSecEncryptSaStatus_xpn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), value));
        }
        else
        {
            value[0] = 1;
            cmd = DRV_IOW(DsXSecDecryptSaStatus_t, DsXSecDecryptSaStatus_nextPn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), value));
        }

    }

    sc_index = p_sc_info->sc_index[dp_id];
    sal_memset(&ds, 0, sizeof(ds));
    if (p_sc_info->dir == CTC_DOT1AE_SC_DIR_RX)
    {
        cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), &ds));

        SetDsXSecDecryptSc(V, xpnExhaustInterruptEn_f, &ds, 1);
        SetDsXSecDecryptSc(V, xpnReachMaxInterruptEn_f, &ds, 0);
        SetDsXSecDecryptSc(A, sci_f, &ds, sci_hw);
        cmd = DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), &ds));
    }
    else
    {
        cmd = DRV_IOR(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), &ds));
        SetDsXSecEncryptSc(V, hwPnSwitch_f, &ds, 1);
        SetDsXSecEncryptSc(V, xpnInterruptEn_f, &ds, 1);
        SetDsXSecEncryptSc(V, xpnReachMaxInterruptEn_f, &ds, 0);
        SetDsXSecEncryptSc(A, sci_f, &ds, sci_hw);
        cmd = DRV_IOW(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), &ds));

        sal_memset(&ds, 0, sizeof(ds));
        SetDsXSecTxScStatus1(V, nextAnReady_f, &ds, 1);
        cmd = DRV_IOW(DsXSecTxScStatus1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, p_sc_info->dp_id), &ds));
    }

    return CTC_E_NONE;
}

 int32 _sys_at_dot1ae_sync_dma_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
 {
     uint8 lchip = 0;
     uint32 secYId = 0;
     uint8 type = 0;
     uint32 i = 0;
     uint32 sc_index =0;
     uint32* p_addr =NULL;
     uint32 dword = 0;
     uint8 tmp_dir=0;
     sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
     sys_at_dot1ae_an_stats_t* p_sys_stats = (sys_at_dot1ae_an_stats_t*)(p_sys_chan->an_stats);
     lchip = traversal_data->value1;
     type = traversal_data->value2;

     tmp_dir = (type%SYS_AT_DOT1AE_STATS_NUM < SYS_AT_DOT1AE_STATS_NUM / 2)? CTC_DOT1AE_SC_DIR_RX : CTC_DOT1AE_SC_DIR_TX;

      if (tmp_dir != p_sys_chan->dir)
      {
         return CTC_E_NONE;
      }

     p_addr = (uint32*)traversal_data->data;
     if (p_sys_chan->binded)
     {
     SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
         if (type / 6 == (p_sys_chan->pp_id*2 + dp_idx))
         {
             switch (type % 6)
             {
                 case 0 :      /*DsXSecRxSecYStats*/
                     dword = TABLE_ENTRY_OFFSET(lchip, DsXSecRxSecYStats_t) >> 2;
                     for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_RX_CHAN_NUM); i++)
                     {
                         secYId  = sys_at_dot1ae_get_secyid(p_sys_chan->pp_id + SYS_PP_BASE(lchip), p_sys_chan->chan_id,dp_idx);
                         if (secYId == i)
                         {
                             p_sys_stats[0].in_pkts_badtag += *(p_addr + secYId*dword) | (uint64)(*(p_addr + secYId*dword+1)&0x3)<<32;
                             p_sys_stats[0].in_pkts_not_using_sa += *(p_addr + secYId*dword+2) | (uint64)(*(p_addr + secYId*dword+3)&0x3)<<32;
                             p_sys_stats[0].in_pkts_unused_sa += *(p_addr + secYId*dword+4) | (uint64)(*(p_addr + secYId*dword+5)&0x3)<<32;
                         }
                     }

                     break;
                 case 1 :      /*DsXSecRxScStats*/
                     dword = TABLE_ENTRY_OFFSET(lchip, DsXSecRxScStats_t) >> 2;
                     for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_RX_CHAN_NUM); i++)
                     {
                         sc_index = p_sys_chan->sc_index[dp_idx];
                         if (sc_index == i)
                         {
                             p_sys_stats[0].in_pkts_ok += *(p_addr + i*dword) | (uint64)(*(p_addr + i*dword+1)&0x3)<<32;
                             p_sys_stats[0].in_pkts_unchecked += *(p_addr + i*dword+2) | (uint64)(*(p_addr + i*dword+3)&0x3)<<32;
                             p_sys_stats[0].in_pkts_delayed += *(p_addr + i*dword+4) | (uint64)(*(p_addr + i*dword+5)&0x3)<<32;
                             p_sys_stats[0].in_pkts_late +=*(p_addr + i*dword+6) | (uint64)(*(p_addr + i*dword+7)&0x3)<<32;
                             p_sys_stats[0].in_pkts_invalid += *(p_addr + i*dword+8) | (uint64)(*(p_addr + i*dword+9)&0x3)<<32;
                             p_sys_stats[0].in_pkts_not_valid += *(p_addr + i*dword+10) | (uint64)(*(p_addr + i*dword+11)&0x3)<<32;
                         }

                     }
                     break;
                 case 2 :     /*DsXSecRxSecYByteStats*/
                     dword = TABLE_ENTRY_OFFSET(lchip, DsXSecRxSecYByteStats_t) >> 2;
                     for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_RX_CHAN_NUM); i++)
                     {
                         secYId  = sys_at_dot1ae_get_secyid(p_sys_chan->pp_id+ SYS_PP_BASE(lchip), p_sys_chan->chan_id,dp_idx);
                         if (secYId == i)
                         {
                             p_sys_stats[0].in_octets_decrypted += *(p_addr + secYId*dword) | (uint64)(*(p_addr + i*secYId+1)&0xFF)<<32;
                             p_sys_stats[0].in_octets_validated += *(p_addr + secYId*dword + 2) | (uint64)(*(p_addr + i*secYId+3)&0xFF)<<32;
                         }
                     }
                     break;
                 case 3 :     /*DsXSecTxSecYStats*/
                     dword = TABLE_ENTRY_OFFSET(lchip, DsXSecTxSecYStats_t) >> 2;
                     for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM); i++)
                     {
                         secYId  = sys_at_dot1ae_get_secyid(p_sys_chan->pp_id+ SYS_PP_BASE(lchip), p_sys_chan->chan_id,dp_idx);
                         if (secYId == i)
                         {
                             p_sys_stats[0].out_pkts_untagged += *(p_addr + secYId*dword) | (uint64)(*(p_addr + secYId*dword+1)&0x3)<<32;
                             p_sys_stats[0].out_pkts_toolong += *(p_addr + secYId*dword + 2) | (uint64)(*(p_addr + secYId*dword+3)&0x3)<<32;
                         }
                     }
                     break;
                 case 4 :     /*DsXSecTxScStats*/
                    dword = TABLE_ENTRY_OFFSET(lchip, DsXSecTxScStats_t) >> 2;
                     for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM); i++)
                     {
                         sc_index = p_sys_chan->sc_index[dp_idx];
                         if (sc_index == i)
                         {
                             p_sys_stats[0].out_pkts_encrypted += *(p_addr + i*dword) | (uint64)(*(p_addr + i*dword+1)&0x3)<<32;
                             p_sys_stats[0].out_pkts_protected += *(p_addr + i*dword + 2) | (uint64)(*(p_addr + i*dword+3)&0x3)<<32;
                             p_sys_stats[0].out_pkts_sa_not_inuse += *(p_addr + i*dword + 4) | (uint64)(*(p_addr + i*dword+5)&0x3)<<32;
                         }

                     }
                     break;
                 case 5 :     /*DsXSecTxSecYByteStats*/
                    dword = TABLE_ENTRY_OFFSET(lchip, DsXSecTxSecYByteStats_t) >> 2;
                     for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM); i++)
                     {
                         secYId  = sys_at_dot1ae_get_secyid(p_sys_chan->pp_id + SYS_PP_BASE(lchip), p_sys_chan->chan_id,dp_idx);
                         if (secYId == i)
                         {
                             p_sys_stats[0].out_octets_encrypted += *(p_addr + secYId*dword) | (uint64)(*(p_addr + i*secYId+1)&0xFF)<<32;
                             p_sys_stats[0].out_octets_protected += *(p_addr + secYId*dword + 2) | (uint64)(*(p_addr + i*secYId+3)&0xFF)<<32;
                         }
                     }

                     break;
                 default:
                     break;
             }
         }
         SYS_DOT1AE_FOREACH_DP_END
     }
     return CTC_E_NONE;
 }

int32
_sys_at_dot1ae_unbind_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32 gport = 0;
    uint8 lchip=0;
    uint32 value =0;
    sys_usw_opf_t opf;
    ctc_slistnode_t        *node = NULL;
    uint32 cmd=0;
    uint8 found = 0;
    uint32 sub_chan_id =0;
    uint8 idx=0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    sys_dot1ae_chan_bind_node_t* p_sec_chan_bind_node = NULL;
    sys_com_dot1ae_bind_sc_t* p_bind_sc = NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)traversal_data->data;
    gport = p_bind_sc->gport;
    lchip = traversal_data->value1;
    dmps_port_info.gport = p_sys_chan->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    if (p_sys_chan->valid&& CTC_SLISTCOUNT(p_sys_chan->bind_mem_list)
        &&(p_sys_chan->binding_type == p_bind_sc->type)&&
        (p_sys_chan->dir == p_bind_sc->dir))
        {
            CTC_SLIST_LOOP(p_sys_chan->bind_mem_list, node)
            {
                p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
                if (p_sys_chan->chan_id == p_bind_sc->chan_id || gport == p_sec_chan_bind_node->value)
                {
                    found = 1;
                    break;
                }
            }
            if (1 == found)
            {
                ctc_slist_delete_node(p_sys_chan->bind_mem_list, &(p_sec_chan_bind_node->head));
                mem_free(p_sec_chan_bind_node);
                if (!CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
                {
                SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
                    opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;

                    opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
                    sys_usw_opf_free_offset(lchip, &opf, 1, p_sys_chan->sc_index[dp_idx]);
                    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_DOT1AE, SYS_WB_APPID_DOT1AE_SUBID_MASTER, 1);

                    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
                    {
                        sal_memset(&ds, 0, sizeof(ds_t));
                        cmd = DRV_IOW(DsXSecTxSaStatus2_t, DRV_ENTRY_FLAG);

                        for (idx = 0; idx < 2; idx++)
                        {
                            uint32 sa_idx = (p_sys_chan->sc_index[dp_idx] << 1) + idx;
                            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sa_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                        }
                        cmd = DRV_IOR(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
                        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                        SetXSecTxLookupChanCtl(V, opType_f, &ds, SYS_DOT1AE_OP_TYPE_BYPASS);
                        cmd = DRV_IOW(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
                        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                    }
                    else
                    {
                        for (idx = 0; idx < 2; idx++)
                        {
                            uint32 sa_idx = (p_sys_chan->sc_index[dp_idx] << 1) + idx;
                            value = 0;
                            cmd = DRV_IOR(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
                            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sa_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                            SetDsXSecDecryptSa(V, enableReceive_f, &ds, value);
                            cmd = DRV_IOW(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
                            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sa_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                        }
                        cmd = DRV_IOR(XSecRxLookupChanCtl_t, DRV_ENTRY_FLAG);
                        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                        SetXSecRxLookupChanCtl(V, opType_f, &ds, SYS_DOT1AE_OP_TYPE_BYPASS);
                        cmd = DRV_IOW(XSecRxLookupChanCtl_t, DRV_ENTRY_FLAG);
                        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                    }
                    p_sys_chan->enable = 0;
                    p_sys_chan->sc_index[dp_idx] = 0;
                    p_sys_chan->binded=0;
                    SYS_DOT1AE_FOREACH_DP_END
                }
            }
        }
            return CTC_E_NONE;
}

int32
_sys_at_get_p2mp_secy_id_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32* p_secy_id = NULL;
    uint32 dp_id =0;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    sys_dot1ae_chan_t* sys_chan = (sys_dot1ae_chan_t*)traversal_data->data1;

    p_secy_id = (uint32*)traversal_data->data;
    dp_id = traversal_data->value1;

    if (p_sys_chan->p2mp && sys_chan->dir == p_sys_chan->dir
        && sys_chan->gport == p_sys_chan->gport)
    {
        *p_secy_id = (p_sys_chan->sc_index[dp_id] <= *p_secy_id)? p_sys_chan->sc_index[dp_id] : *p_secy_id;
    }
        return CTC_E_NONE;
}

STATIC uint32
_sys_at_dot1ae_alloc_secy_id(uint8 lchip, sys_dot1ae_chan_t* sys_chan,uint8 dp_id)
{
    sys_traverse_t user_data;
    uint32 secy_id = sys_chan->sc_index[dp_id];

    if (!sys_chan->p2mp)
    {
        return sys_chan->sc_index[dp_id];
    }

    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.value1 = dp_id;
    user_data.data = &secy_id;
    user_data.data1 = sys_chan;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_at_get_p2mp_secy_id_traverse, (void *)&user_data));
    return secy_id;
}

STATIC uint32
_sys_at_dot1ae_clear_tag_mapping(uint8 lchip, uint8 clear_tag, uint8 unmapping, uint8 is_mac_key)
{
    uint8 clear_tag_map = 0;
    if (!unmapping)
    {
        switch (clear_tag)
        {
            default:
                clear_tag_map = is_mac_key? SYS_DOT1AE_SEGTAG_OFFSET_L2_OFFSET : SYS_DOT1AE_SEGTAG_OFFSET_L3_L4_OFFSET;
                break;
        }
    }
    else
    {
        switch (clear_tag)
        {
            case SYS_DOT1AE_SEGTAG_OFFSET_SINGLE_VLAN:
                clear_tag_map = CTC_DOT1AE_CLEAR_TAG_SINGLE;
                break;
            case SYS_DOT1AE_SEGTAG_OFFSET_DOUBLE_VLAN:
                clear_tag_map = CTC_DOT1AE_CLEAR_TAG_DOUBLE;
                break;
            default:
                break;
        }

    }
    return clear_tag_map;
}


int32
sys_at_dot1ae_add_sc_to_asic(uint8 lchip, void* sys_chan)
{
    uint32 cmd = 0;
    uint32 sci_hw[2] ={0};
    uint32 sc_idx = 0;
    ds_t ds;
    uint32 secy_index=0;
    uint8 dp_id = 0;
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;

    dp_id = p_sys_chan->dp_id;
    sc_idx = p_sys_chan->sc_index[dp_id];
    secy_index = _sys_at_dot1ae_alloc_secy_id(lchip,p_sys_chan,dp_id);

    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
    {
        cmd = DRV_IOR(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecDecryptSecY(V, controlledPortEnabled_f, &ds, 1);
        SetDsXSecDecryptSecY(V, validateFrames_f, &ds, p_sys_chan->validateFrames);
        SetDsXSecDecryptSecY(V, replayProtect_f, &ds, p_sys_chan->replayProtect);
        SetDsXSecDecryptSecY(V, replayProtectWindow_f, &ds, p_sys_chan->replayProtectWindow);
        cmd = DRV_IOW(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

        if (p_sys_chan->sci)
        {
            SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)p_sys_chan->sci, sizeof(sci_hw));
        }
        cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecDecryptSc(V, saValid_f, &ds, p_sys_chan->an_valid &0xF);
        SetDsXSecDecryptSc(A, sci_f, &ds, sci_hw);
        SetDsXSecDecryptSc(V, isXpnMode_f, &ds, p_sys_chan->is_xpn);
        SetDsXSecDecryptSc(V, compatibleMode_f, &ds, p_sys_chan->protocol_type?1:0);
        cmd = DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

        cmd = DRV_IOR(DsXSecDecryptScPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecDecryptScPre(V, secYId_f, &ds, secy_index);
        SetDsXSecDecryptScPre(V, icvCalcMode_f, &ds,(p_sys_chan->binding_type||p_sys_chan->clear_tag_en)? 1 : 0);
        cmd = DRV_IOW(DsXSecDecryptScPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
    }
    else
    {
        cmd = DRV_IOR(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        if (p_sys_chan->sci)
        {
            SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)p_sys_chan->sci, sizeof(sci_hw));
        }
        SetDsXSecEncryptSc(A, sci_f, &ds, sci_hw);
        SetDsXSecEncryptSc(V, isXpnMode_f, &ds, p_sys_chan->is_xpn);
        cmd = DRV_IOW(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

        cmd = DRV_IOR(DsXSecEncryptScPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecEncryptScPre(V, secYId_f, &ds, secy_index);
        SetDsXSecEncryptScPre(V, ctcSecShimValid_f, &ds, p_sys_chan->with_ctc_sh? 1 : 0);
        cmd = DRV_IOW(DsXSecEncryptScPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

        cmd = DRV_IOR(DsXSecEncryptSecY_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecEncryptSecY(V, maxLen_f, &ds, SYS_DOT1AE_PACKET_MAX_LENTH);
        SetDsXSecEncryptSecY(V, maxLenChk_f, &ds, 1);
        SetDsXSecEncryptSecY(V, secYEtherTypeProfileId_f, &ds, p_sys_chan->protocol_type? 2 : 0);
        cmd = DRV_IOW(DsXSecEncryptSecY_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

        cmd = DRV_IOR(DsXSecEncryptSecYPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecEncryptSecYPre(V, controlledPortEnabled_f, &ds, 1);
        SetDsXSecEncryptSecYPre(V, protectFrames_f, &ds, 1);
        SetDsXSecEncryptSecYPre(V, p2mpSecY_f, &ds, p_sys_chan->p2mp);
        SetDsXSecEncryptSecYPre(V, alwaysIncludeSci_f, &ds, p_sys_chan->include_sci);
        cmd = DRV_IOW(DsXSecEncryptSecYPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

    }
    return CTC_E_NONE;
}


int32
sys_at_dot1ae_add_sa_to_asic(uint8 lchip, void* sys_chan, uint8 sa_idx, uint32 update_flag)
{
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 key_hw[8] = {0};
    uint32 salt_hw[3] ={0};
    uint32 sc_idx = 0;
    uint32 cipher_mode = 0;
    uint32 key_index = 0;
    uint32 sa_offst =0;
    uint32 val_ary[2]={0};
    uint8 key_len = 0;
    ds_t ds;
    uint32 secy_index=0;
    uint8 dp_id = 0;

    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;

    dp_id = p_sys_chan->dp_id;
    sc_idx = p_sys_chan->sc_index[dp_id];
    key_index =  (p_sys_chan->sc_index[dp_id] << 1)  + (sa_idx & 0x1);
    secy_index = sys_at_dot1ae_get_secyid(lchip,p_sys_chan->chan_id,dp_id);

    /* map cipher mode */
    /*For SegTag offset !=12 in asic, cipher_mode must set to 4 or 5,
    and maping to API which the value 0 and 3,which means enable and disable encrypt/decrypt */
    cipher_mode = p_sys_chan->sa_cfg[sa_idx].cipher_mode;
    if (p_sys_chan->binding_type != 0
        ||p_sys_chan->clear_tag_en)
    {
        if (cipher_mode == SYS_DOT1AE_ENCRYPT_OFFSET_30 || cipher_mode == SYS_DOT1AE_ENCRYPT_OFFSET_50 )
        {
            return CTC_E_INVALID_CONFIG;
        }
        if (cipher_mode == SYS_DOT1AE_ENCRYPT_OFFSET_0)
        {
            if (1 == SDK_WORK_PLATFORM&&p_sys_chan->clear_tag_en)
            {
               cipher_mode = SYS_DOT1AE_ENCRYPT_OFFSET_0; /*Because of cmodel problems for Wansec*/
            }
            else
            {
                cipher_mode = SYS_DOT1AE_ENCRYPT_OFFSET_FROM_TAG;
            }
        }
        else if (cipher_mode == SYS_DOT1AE_ICV_CAL_OFFSET_0)
        {
            cipher_mode = SYS_DOT1AE_ICV_CAL_OFFSET_FROM_TAG;
        }
    }

    /* get next_pn */
    val_ary[0] = p_sys_chan->sa_cfg[sa_idx].next_pn&0xFFFFFFFF;
    val_ary[1] = (p_sys_chan->sa_cfg[sa_idx].next_pn >> 32)&0xFFFFFFFF;

    /* convert key to HW byte order */
    key_len = (CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite
        || CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite)?(CTC_DOT1AE_KEY_LEN / 2):CTC_DOT1AE_KEY_LEN;
    SYS_USW_SET_HW_VALUE(key_hw, p_sys_chan->sa_cfg[sa_idx].key, key_len);
    SYS_USW_SET_HW_VALUE(salt_hw, p_sys_chan->sa_cfg[sa_idx].salt, sizeof(salt_hw));

    value = CTC_IS_BIT_SET(p_sys_chan->an_en, p_sys_chan->sa_cfg[sa_idx].an);

    /* set sa cfg to asic if flag is set */
    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
    {
        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_KEY))
        {
            cmd = DRV_IOR(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecDecryptSa(A, decryptKey_f, &ds, key_hw);
            SetDsXSecDecryptSa(A, u_gSecY_salt_f, &ds, salt_hw);
            SetDsXSecDecryptSa(V, u_gSecY_ssci_f, &ds, p_sys_chan->sa_cfg[sa_idx].ssci);
            SetDsXSecDecryptSa(V, keyLenType_f, &ds, (p_sys_chan->sa_cfg[sa_idx].cipher_suite)%2);
            SetDsXSecDecryptSa(V, enableReceive_f, &ds, value);
            cmd = DRV_IOW(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

            cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecDecryptSc(V, isXpnMode_f, &ds, p_sys_chan->is_xpn);
            cmd = DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }

        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_ENCRYPTION))
        {
            cmd = DRV_IOR(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecDecryptSa(V, u_gSecY_cipherMode_f, &ds, cipher_mode);
            cmd = DRV_IOW(DsXSecDecryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }


        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_NEXT_PN))
        {
            cmd = DRV_IOR(DsXSecDecryptSaStatus_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecDecryptSaStatus(A, nextPn_f, &ds, val_ary);
            cmd = DRV_IOW(DsXSecDecryptSaStatus_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }

        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_VALIDATEFRAMES))
        {
            cmd = DRV_IOR(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecDecryptSecY(V, validateFrames_f, &ds, p_sys_chan->validateFrames);
            cmd = DRV_IOW(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secy_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }

        cmd = DRV_IOR(DsXSecDecryptScPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        sa_offst = GetDsXSecDecryptScPre(V, saOffset_f, &ds);
        if (sa_idx)
        {
            CTC_BIT_SET(sa_offst, p_sys_chan->sa_cfg[sa_idx].an);
        }
        else if (!sa_idx)
        {
            CTC_BIT_UNSET(sa_offst, p_sys_chan->sa_cfg[sa_idx].an);
        }
        SetDsXSecDecryptScPre(V, saOffset_f, &ds, sa_offst);
        cmd = DRV_IOW(DsXSecDecryptScPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

        cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecDecryptSc(V, saValid_f, &ds, p_sys_chan->an_valid);
        cmd = DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

    }
    else
    {
        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_KEY))
        {
            cmd = DRV_IOR(DsXSecEncryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecEncryptSa(A, encryptKey_f, &ds, key_hw);
            SetDsXSecEncryptSa(A, u_gSecY_salt_f, &ds, salt_hw);
            SetDsXSecEncryptSa(V, u_gSecY_ssci_f, &ds, p_sys_chan->sa_cfg[sa_idx].ssci);
            SetDsXSecEncryptSa(V, keyLenType_f, &ds, (p_sys_chan->sa_cfg[sa_idx].cipher_suite)%2);
            SetDsXSecEncryptSa(V, u_gSecY_encodingAn_f, &ds, p_sys_chan->sa_cfg[sa_idx].an);
            cmd = DRV_IOW(DsXSecEncryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));

            cmd = DRV_IOR(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecEncryptSc(V, isXpnMode_f, &ds, p_sys_chan->is_xpn);
            cmd = DRV_IOW(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }

        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_ENCRYPTION))
        {
            cmd = DRV_IOR(DsXSecEncryptSaPre_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecEncryptSaPre(V, u_gSecY_cipherMode_f, &ds, cipher_mode);
            cmd = DRV_IOW(DsXSecEncryptSaPre_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }

        if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_NEXT_PN))
        {
            cmd = DRV_IOR(DsXSecEncryptSaStatus_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
            SetDsXSecEncryptSaStatus(A, xpn_f, &ds, val_ary);
            cmd = DRV_IOW(DsXSecEncryptSaStatus_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }
        sal_memset(&ds, 0, sizeof(ds));
        cmd = DRV_IOW(DsXSecTxScStatus0_t, DRV_ENTRY_FLAG);
        if (value && sa_idx)
        {
            SetDsXSecTxScStatus0(V, encodingSa_f, &ds, 1);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }
        else if (value && !sa_idx)
        {
            SetDsXSecTxScStatus0(V, encodingSa_f, &ds, 0);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        }

        cmd = DRV_IOR(DsXSecTxSaStatus2_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        SetDsXSecTxSaStatus2(V, enableTransmit_f, &ds, 1);
        cmd = DRV_IOW(DsXSecTxSaStatus2_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
    }

    return CTC_E_NONE;
}



STATIC int32
_sys_at_dot1ae_update_global_pn_mode_traverse(sys_dot1ae_chan_t* p_sys_chan, void* user_data)
{
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    uint32 value = traversal_data->value1;
    uint8 lchip = traversal_data->value2;
    uint32 cmd =0;
    uint32 sc_idx = 0;
    ds_t ds;

    if (p_sys_chan->pn_mode == CTC_DOT1AE_SC_PN_MODE_NONE)
    {
        p_sys_chan->is_xpn =  usw_dot1ae_master[lchip]->is_xpn;
    }
    if (p_sys_chan->pn_mode == CTC_DOT1AE_SC_PN_MODE_NONE
        &&p_sys_chan->binded)
    {
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
        sc_idx = p_sys_chan->sc_index[dp_idx];

        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG) : DRV_IOR(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)?SetDsXSecDecryptSc(V, isXpnMode_f, &ds, value): SetDsXSecEncryptSc(V, isXpnMode_f, &ds, value);
        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG) : DRV_IOW(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_idx, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        SYS_DOT1AE_FOREACH_DP_END
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_update_global_pn_mode(uint8 lchip, uint8 is_xpn)
{
    sys_traverse_t user_data;
    sal_memset(&user_data, 0 ,sizeof(sys_traverse_t));
    user_data.value1 = is_xpn;
    user_data.value2 = lchip;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_at_dot1ae_update_global_pn_mode_traverse, (void *)&user_data));
    return CTC_E_NONE;
}


int32
_sys_at_get_secy_stats_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32 gport = 0;
    uint8 dir =0;
    uint8 lchip = 0;
    ctc_dot1ae_an_stats_t stats;
    sys_at_dot1ae_an_stats_t* p_sys_stats = (sys_at_dot1ae_an_stats_t*)(p_sys_chan->an_stats);
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    ctc_dot1ae_an_stats_t*p_stats = (ctc_dot1ae_an_stats_t*)traversal_data->data;
    gport = traversal_data->value1;
    dir =  traversal_data->value2;
    lchip = traversal_data->value3;
    sal_memset(&stats, 0 , sizeof(ctc_dot1ae_an_stats_t));
    if ((dir ==p_sys_chan->dir)&&p_sys_chan->binded)
    {
        if ((p_sys_chan->gport == gport) && (!p_sys_chan->binding_type))
        {
            sys_at_dot1ae_get_stats(lchip, p_sys_chan->chan_id, (void*)&stats);

            if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
            {
                p_stats->out_pkts_untagged +=  p_sys_stats[0].out_pkts_untagged;
                p_stats->out_pkts_toolong +=  p_sys_stats[0].out_pkts_toolong;
                p_stats->out_octets_encrypted +=  p_sys_stats[0].out_octets_encrypted;
                p_stats->out_octets_protected +=  p_sys_stats[0].out_octets_protected;
            }
            else
            {
                p_stats->in_pkts_badtag +=  p_sys_stats[0].in_pkts_badtag;
                p_stats->in_octets_decrypted +=  p_sys_stats[0].in_octets_decrypted;
                p_stats->in_octets_validated +=  p_sys_stats[0].in_octets_validated;
                p_stats->in_pkts_not_using_sa += p_sys_stats[0].in_pkts_not_using_sa;
                p_stats->in_pkts_unused_sa += p_sys_stats[0].in_pkts_unused_sa;
            }
        }

    }
     return CTC_E_NONE;
}

 int32
sys_at_dot1ae_get_secyid(uint8 lchip, uint32  chan_id,uint8 dp_id)
{
    uint32 cmd = 0;
    uint32 secYId = 0;
    uint32 tbl_id=0;
    uint16 field_id=0;
    ds_t ds;
    sys_dot1ae_chan_t* p_sys_sec_chan = NULL;
    SYS_DOT1AE_INIT_CHECK(lchip);
    p_sys_sec_chan = _sys_usw_dot1ae_chan_lookup(lchip, chan_id);
    if (!p_sys_sec_chan)
    {
        return CTC_E_NOT_EXIST;
    }
    tbl_id = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX)? DsXSecEncryptScPre_t : DsXSecDecryptScPre_t;
    field_id = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX)? DsXSecEncryptScPre_secYId_f : DsXSecDecryptScPre_secYId_f;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_sec_chan->sc_index[dp_id], DRV_CMD_DP_EN(cmd, dp_id), &ds));
    secYId= DRV_GET_FIELD_V(lchip, tbl_id, field_id, &ds);
    return secYId;
}

STATIC int32
_sys_at_dot1ae_add_mac_key_field(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry, void*p_field, uint32 hash_key[])
{
    void* ext_data = NULL;
    ctc_field_key_t* p_dot1ae_field=NULL;
    uint32 sci_hw[2]={0};
    uint32 field_id =0;
    uint32 data=0;
    uint32 tbl_id=0;
    uint32 sub_chan = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    p_dot1ae_field=(ctc_field_key_t*)p_field;
    ext_data = p_dot1ae_field->ext_data;
    data = p_dot1ae_field->data;
    tbl_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxL2BasicHashKey_t : DsXSecRxL2MacsecHashKey_t;
    if (p_sys_dot1ae_entry->dir == CTC_EGRESS)
    {
        SetDsXSecTxL2BasicHashKey(V, keyType0_f, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetDsXSecTxL2BasicHashKey(V, keyType1_f, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
    }
    else
    {
        SetDsXSecRxL2MacsecHashKey(V, keyType_f, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_MACSEC);
        SetDsXSecRxL2MacsecHashKey(V, isMacsec_f, hash_key, 1);
    }
    switch (p_dot1ae_field->type)
    {
    case CTC_FIELD_KEY_DOT1AE_SCI:
        if (!ext_data || (p_sys_dot1ae_entry->dir == CTC_EGRESS))
        {
            return CTC_E_INVALID_PARAM;
        }
        SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)ext_data, sizeof(sci_hw));
        SetDsXSecRxL2MacsecHashKey(A, sci_f, hash_key, sci_hw);
        break;
    case CTC_FIELD_KEY_SVLAN_ID:
        field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxL2BasicHashKey_svlanId_f : DsXSecRxL2MacsecHashKey_svlanId_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
        break;
    case CTC_FIELD_KEY_CVLAN_ID:
        field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxL2BasicHashKey_cvlanId_f : DsXSecRxL2MacsecHashKey_cvlanId_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
        break;
    case CTC_FIELD_KEY_PORT:
        dmps_port_info.gport = data;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
        field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxL2BasicHashKey_chanLabel_f : DsXSecRxL2MacsecHashKey_chanLabel_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, sub_chan);
        p_sys_dot1ae_entry->gport = data;
        SYS_DOT1AE_GET_DP_BMP(lchip,data,p_sys_dot1ae_entry->dp_bmp);
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_add_ipv4_key_field(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry, void*p_field, uint32 hash_key[])
{
    uint32 tbl_id=0;
    uint16 field_id=0;
    uint32 data=0;
    uint32 sub_chan = 0;
    ctc_field_key_t* p_dot1ae_field=NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    p_dot1ae_field = (ctc_field_key_t*)p_field;
    data = p_dot1ae_field->data;
    tbl_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_t : DsXSecRxL3L4V4HashKey_t;
    field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_keyType_f : DsXSecRxL3L4V4HashKey_keyType_f;
    DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);

    if (p_sys_dot1ae_entry->dir == CTC_INGRESS)
    {
        field_id=  DsXSecRxL3L4V4HashKey_isCtcSec_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, 1);
    }

    switch (p_dot1ae_field->type)
    {
        case CTC_FIELD_KEY_IP_SA:
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_ipSa_f : DsXSecRxL3L4V4HashKey_ipSa_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_IP_DA:
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_ipDa_f : DsXSecRxL3L4V4HashKey_ipDa_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_IP_PROTOCOL:
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_ipProtocol_f : DsXSecRxL3L4V4HashKey_ipProtocol_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_L4_SRC_PORT:
            if (p_sys_dot1ae_entry->dir == CTC_INGRESS)
            {
                field_id=  DsXSecRxL3L4V4HashKey_ctcSecType_f;
                DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, 1);
            }
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_l4SourcePort_f : DsXSecRxL3L4V4HashKey_l4SourcePort_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_L4_DST_PORT:
            if (p_sys_dot1ae_entry->dir == CTC_INGRESS)
            {
                field_id=  DsXSecRxL3L4V4HashKey_ctcSecType_f;
                DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, 1);
            }
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V4HashKey_l4DestPort_f : DsXSecRxL3L4V4HashKey_l4DestPort_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_PORT:
            dmps_port_info.gport = data;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxL3L4V4HashKey_chanLabel_f : DsXSecRxL3L4V4HashKey_chanLabel_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, sub_chan);
            p_sys_dot1ae_entry->gport = data;
            SYS_DOT1AE_GET_DP_BMP(lchip,data,p_sys_dot1ae_entry->dp_bmp);

            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_add_ipv6_key_field(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry, void*p_field, uint32 hash_key[])
{
    uint32 tbl_id=0;
    uint16 field_id=0;
    uint32 data=0;
    uint32 hw_ipv6[2]={0};
    uint32 sub_chan = 0;
    void* ext_data = NULL;
    ctc_field_key_t* p_dot1ae_field=NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    p_dot1ae_field = (ctc_field_key_t*)p_field;
    ext_data = p_dot1ae_field->ext_data;
    data = p_dot1ae_field->data;
    if ((p_dot1ae_field->type == CTC_FIELD_KEY_IPV6_SA
        || p_dot1ae_field->type == CTC_FIELD_KEY_IPV6_DA)
    && (!ext_data))
    {
        return CTC_E_INVALID_PARAM;
    }
    else if(ext_data)
    {
        hw_ipv6[0] = *((uint32*)ext_data + 1);
        hw_ipv6[1] = *((uint32*)ext_data);
    }
    tbl_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_t : DsXSecRxL3L4V6HashKey_t;
    field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_keyType0_f : DsXSecRxL3L4V6HashKey_keyType0_f;
    DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
    field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_keyType1_f : DsXSecRxL3L4V6HashKey_keyType1_f;
    DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);

    if (p_sys_dot1ae_entry->dir == CTC_INGRESS)
    {
        field_id=  DsXSecRxL3L4V6HashKey_isCtcSec_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, 1);
    }

    switch (p_dot1ae_field->type)
    {
        case CTC_FIELD_KEY_IPV6_SA:
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_ipSa_f : DsXSecRxL3L4V6HashKey_ipSa_f;
            DRV_SET_FIELD_A(lchip, tbl_id, field_id, hash_key, hw_ipv6);
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_ipSaExt_f : DsXSecRxL3L4V6HashKey_ipSaExt_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, (*((uint32*)ext_data+2))>>16);
            break;
        case CTC_FIELD_KEY_IPV6_DA:
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_ipDa_f : DsXSecRxL3L4V6HashKey_ipDa_f;
            DRV_SET_FIELD_A(lchip, tbl_id, field_id, hash_key, hw_ipv6);
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_ipDaExt_f : DsXSecRxL3L4V6HashKey_ipDaExt_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, (*((uint32*)ext_data+2))>>16);
            break;
        case CTC_FIELD_KEY_IP_PROTOCOL:
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_ipProtocol_f : DsXSecRxL3L4V6HashKey_ipProtocol_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_L4_SRC_PORT:
            if (p_sys_dot1ae_entry->dir == CTC_INGRESS)
            {
                field_id=  DsXSecTxL3L4V6HashKey_ctcSecType_f;
                DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, 1);
            }
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_l4SourcePort_f : DsXSecRxL3L4V6HashKey_l4SourcePort_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
        case CTC_FIELD_KEY_L4_DST_PORT:
            if (p_sys_dot1ae_entry->dir == CTC_INGRESS)
            {
                field_id=  DsXSecTxL3L4V6HashKey_ctcSecType_f;
                DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, 1);
            }
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxL3L4V6HashKey_l4DestPort_f : DsXSecRxL3L4V6HashKey_l4DestPort_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
            break;
       case CTC_FIELD_KEY_PORT:
            dmps_port_info.gport = data;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
            field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxL3L4V6HashKey_chanLabel_f : DsXSecRxL3L4V6HashKey_chanLabel_f;
            DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, sub_chan);
            p_sys_dot1ae_entry->gport = data;
            SYS_DOT1AE_GET_DP_BMP(lchip,data,p_sys_dot1ae_entry->dp_bmp);
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_add_spi_key_field(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry, void*p_field, uint32 hash_key[])
{
    uint32 tbl_id = 0;
    uint16 field_id = 0;
    uint32 data = 0;
    uint32 sub_chan = 0;
    ctc_field_key_t* p_dot1ae_field=NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    p_dot1ae_field = (ctc_field_key_t*)p_field;
    data = p_dot1ae_field->data;

    tbl_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxSpiHashKey_t : DsXSecRxSpiHashKey_t;
    field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxSpiHashKey_keyType_f : DsXSecRxSpiHashKey_keyType_f;
    DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_SPI);

    if (p_dot1ae_field->type == CTC_FIELD_KEY_DOT1AE_SPI)
    {
        field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)? DsXSecTxSpiHashKey_ctcSecValue0_f : DsXSecRxSpiHashKey_ctcSecValue0_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, data);
    }
    else if (p_dot1ae_field->type == CTC_FIELD_KEY_PORT)
    {
        dmps_port_info.gport = data;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
        field_id = (p_sys_dot1ae_entry->dir == CTC_EGRESS)?  DsXSecTxSpiHashKey_chanLabel_f : DsXSecRxSpiHashKey_chanLabel_f;
        DRV_SET_FIELD_V(lchip, tbl_id, field_id, hash_key, sub_chan);
        p_sys_dot1ae_entry->gport = data;
        SYS_DOT1AE_GET_DP_BMP(lchip,data,p_sys_dot1ae_entry->dp_bmp);
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_add_l2ext_key_field(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry, void*p_field, uint32 hash_key[])
{
    ctc_field_key_t* p_dot1ae_field=NULL;
    uint32 data=0;
    uint32 sub_chan_id = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    p_dot1ae_field=(ctc_field_key_t*)p_field;
    data = p_dot1ae_field->data;

    SetDsXSecRxL2BasicHashKey(V, keyType0_f, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
    SetDsXSecRxL2BasicHashKey(V, keyType1_f, hash_key, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);

    switch (p_dot1ae_field->type)
    {
        case CTC_FIELD_KEY_SVLAN_ID:
            DRV_SET_FIELD_V(lchip, DsXSecRxL2BasicHashKey_t, DsXSecRxL2BasicHashKey_svlanId_f, hash_key, data);
            break;
        case CTC_FIELD_KEY_CVLAN_ID:
            DRV_SET_FIELD_V(lchip, DsXSecRxL2BasicHashKey_t, DsXSecRxL2BasicHashKey_cvlanId_f, hash_key, data);
            break;
        case CTC_FIELD_KEY_PORT:
            dmps_port_info.gport = data;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
            DRV_SET_FIELD_V(lchip, DsXSecRxL2BasicHashKey_t, DsXSecRxL2BasicHashKey_chanLabel_f, hash_key, sub_chan_id);
            p_sys_dot1ae_entry->gport = data;
            SYS_DOT1AE_GET_DP_BMP(lchip,data,p_sys_dot1ae_entry->dp_bmp);
            break;
        case CTC_FIELD_KEY_ETHER_TYPE:
            DRV_SET_FIELD_V(lchip, DsXSecRxL2BasicHashKey_t, DsXSecRxL2BasicHashKey_etherType_f, hash_key, data);
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;

}

int32
_sys_at_dot1ae_add_key_field(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry,
                                        void*p_field,uint32 hash_key[])
{

    switch (p_sys_dot1ae_entry->key_type)
    {
        case CTC_DOT1AE_KEY_L2:
            CTC_ERROR_RETURN(_sys_at_dot1ae_add_l2ext_key_field(lchip, p_sys_dot1ae_entry, p_field, hash_key));
            break;
        case CTC_DOT1AE_KEY_MACSEC:
        CTC_ERROR_RETURN(_sys_at_dot1ae_add_mac_key_field(lchip, p_sys_dot1ae_entry, p_field, hash_key));
            break;
        case CTC_DOT1AE_KEY_IPV4:
            CTC_ERROR_RETURN(_sys_at_dot1ae_add_ipv4_key_field(lchip, p_sys_dot1ae_entry, p_field, hash_key));
            break;
        case CTC_DOT1AE_KEY_IPV6:
            CTC_ERROR_RETURN(_sys_at_dot1ae_add_ipv6_key_field(lchip, p_sys_dot1ae_entry, p_field, hash_key));
            break;
        case CTC_DOT1AE_KEY_SPI:
            CTC_ERROR_RETURN(_sys_at_dot1ae_add_spi_key_field(lchip, p_sys_dot1ae_entry, p_field, hash_key));
            break;
        default:
            break;
    }
    return CTC_E_NONE;
}

int32
sys_at_dot1ae_build_key(uint8 lchip, sys_dot1ae_entry_t* p_sys_dot1ae_entry,ctc_dot1ae_entry_t* p_ctc_entry,uint32 hash_key[])
{
    int32   ret           = CTC_E_NONE;
    uint32  field_id      = 0;
    uint32  field_cnt     = 0;
    void*   p_field       = NULL;

    field_cnt = p_ctc_entry->field_cnt;
    for (field_id = 0; field_id < field_cnt; field_id += 1)
    {
        p_field = (void*)((ctc_field_key_t*)p_ctc_entry->p_field_key + field_id);
        ret = _sys_at_dot1ae_add_key_field(lchip, p_sys_dot1ae_entry,p_field,hash_key);
        if (CTC_E_NONE != ret)
        {
            break;
        }
    }
    if (CTC_E_NONE != ret)
    {
        p_ctc_entry->field_cnt = field_id;
    }
    return ret;
}

STATIC
int32 _sys_at_dot1ae_get_tbl_id(uint8 lchip,uint8 key_type,uint8 dir, uint32 *tbl_id,uint8 *key_size)
{
    uint8 key_size_rx[CTC_DOT1AE_KEY_MAX] ={0,0,/* DsXSecRxL2BasicHashKey_t, double key, 228-bit width*/
                                              1,/* DsXSecRxL2MacsecHashKey_t, single key, 114-bit width*/
                                              0,/* DsXSecRxL3L4V4HashKey_t, single key, 114-bit width*/
                                              1,/* DsXSecRxL3L4V6HashKey_t, double key, 228-bit width */
                                              0};/* DsXSecRxSpiHashKey_t, single key, 114-bit width  */
    uint8 key_size_tx[CTC_DOT1AE_KEY_MAX] ={0,0,
                                              1,/* DsXSecTxL2BasicHashKey_t, double key, 228-bit width*/
                                              0,/* DsXSecTxL3L4V4HashKey_t, single key, 114-bit width*/
                                              1,/* DsXSecTxL3L4V6HashKey_t, double key, 228-bit width */
                                              0};/* DsXSecTxSpiHashKey_t, single key, 114-bit width  */

    uint32 key_tbl_id_rx[CTC_DOT1AE_KEY_MAX] = {0, DsXSecRxL2BasicHashKey_t, /* CTC_DOT1AE_KEY_L2 */
                                                   DsXSecRxL2MacsecHashKey_t,/* CTC_DOT1AE_KEY_MACSEC */
                                                   DsXSecRxL3L4V4HashKey_t,  /* CTC_DOT1AE_KEY_IPV4 */
                                                   DsXSecRxL3L4V6HashKey_t,  /* CTC_DOT1AE_KEY_IPV6 */
                                                   DsXSecRxSpiHashKey_t};    /* CTC_DOT1AE_KEY_SPI */
    uint32 key_tbl_id_tx[CTC_DOT1AE_KEY_MAX] = {0, 0,
                                                   DsXSecTxL2BasicHashKey_t,/* CTC_DOT1AE_KEY_MACSEC */
                                                   DsXSecTxL3L4V4HashKey_t,  /* CTC_DOT1AE_KEY_IPV4 */
                                                   DsXSecTxL3L4V6HashKey_t,  /* CTC_DOT1AE_KEY_IPV6 */
                                                   DsXSecTxSpiHashKey_t};    /* CTC_DOT1AE_KEY_SPI */
    CTC_MAX_VALUE_CHECK(key_type, CTC_DOT1AE_KEY_MAX-1);

    if (tbl_id)
    {
        *tbl_id = (CTC_INGRESS == dir) ? key_tbl_id_rx[key_type] : key_tbl_id_tx[key_type];
    }
    if (key_size)
    {
        *key_size = (CTC_INGRESS == dir) ? key_size_rx[key_type] : key_size_tx[key_type] ;
    }
    return CTC_E_NONE;
}

int32
sys_at_dot1ae_build_sc_index(uint8 lchip, void* sys_chan)
{
    uint32 dp_id = 0;
    sys_dot1ae_chan_t* p_sys_sec_chan = (sys_dot1ae_chan_t*)sys_chan;
    uint32  offset = 0;
    sys_usw_opf_t opf;

    /* 1. get dp-id using gport */
    SYS_DOT1AE_GET_DP_ID(lchip, p_sys_sec_chan->gport,dp_id);
    p_sys_sec_chan->dp_id = dp_id;
    CTC_BIT_SET(p_sys_sec_chan->dp_bmp, dp_id);

    /* 2. alloc sc index per dp */
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
    opf.pool_index = ((p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (p_sys_sec_chan->dp_id?2:0);
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, 1, &offset));
    p_sys_sec_chan->sc_index[dp_id] = offset & 0x7f;
    p_sys_sec_chan->alloced_source = 1;

    return CTC_E_NONE;
}

int32 _sys_at_dot1ae_build_key_index(uint8 lchip,sys_dot1ae_entry_t* p_sys_dot1ae_entry, uint32 hash_key[],uint8 dp_id)
{

    drv_acc_in_t  lookup_info;
    drv_acc_out_t lookup_result;
    uint32 tbl_id=0;
    uint8 key_size=0;

    sal_memset(&lookup_info, 0, sizeof(lookup_info));
    sal_memset(&lookup_result, 0, sizeof(lookup_result));

    CTC_ERROR_RETURN(_sys_at_dot1ae_get_tbl_id(lchip, p_sys_dot1ae_entry->key_type,p_sys_dot1ae_entry->dir, &tbl_id,&key_size));

    lookup_info.type = DRV_ACC_TYPE_LOOKUP;
    lookup_info.op_type = DRV_ACC_OP_BY_KEY;
    lookup_info.data = hash_key;
    lookup_info.tbl_id = tbl_id;
    lookup_info.dir = p_sys_dot1ae_entry->dir;
    lookup_info.oper_bmp = DRV_ACC_DP_EN(dp_id);
    lookup_info.dp_id = dp_id;
    lookup_info.value = key_size;
    drv_acc_get_hash_module(lchip, lookup_info.tbl_id, &lookup_info.module);
    CTC_ERROR_RETURN(drv_acc_api(lchip, &lookup_info, &lookup_result));

    p_sys_dot1ae_entry->hash_key_index[dp_id] = lookup_result.key_index;
    p_sys_dot1ae_entry->is_cam[dp_id] = lookup_result.data[0];

    if (!lookup_result.is_hit && !lookup_result.is_conflict)
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "tbl_id:%u, index->0x%x\n", tbl_id, lookup_result.key_index);
    }
    else if (lookup_result.is_conflict)
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Hash Conflict \n");
        return CTC_E_HASH_CONFLICT;
    }
    else if (lookup_result.is_hit)
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry already exist \n");
        return CTC_E_EXIST;
    }

    return CTC_E_NONE;
}

 int32
sys_at_dot1ae_key_ad_write_io(uint8 lchip,sys_dot1ae_entry_t* p_sys_dot1ae_entry, uint32 hash_key[], uint8 is_remove,uint8 dp_id)
{
    uint32 ad_tbl_id=0;
    drv_acc_in_t  lookup_info;
    drv_acc_out_t lookup_result;
    uint32 cmd=0;
    uint32 tbl_id=0;
    ds_t ds;
    uint8 is_mac_key =0;
    uint8 is_rx_plain = 0;

    sal_memset(&lookup_info, 0, sizeof(lookup_info));
    sal_memset(&lookup_result, 0, sizeof(lookup_result));
    CTC_ERROR_RETURN(_sys_at_dot1ae_get_tbl_id(lchip, p_sys_dot1ae_entry->key_type,p_sys_dot1ae_entry->dir, &tbl_id,NULL));

    lookup_info.type = DRV_ACC_TYPE_ADD;
    lookup_info.op_type = DRV_ACC_OP_BY_INDEX;
    if (is_remove)
    {
        sal_memset(ds, 0, sizeof(ds_t));
        lookup_info.data = ds;
    }
    else
    {
        lookup_info.data = hash_key;
    }
    lookup_info.tbl_id = tbl_id;
    lookup_info.index = p_sys_dot1ae_entry->hash_key_index[dp_id];
    lookup_info.dir = p_sys_dot1ae_entry->dir;
    lookup_info.oper_bmp = DRV_ACC_DP_EN(dp_id);
    lookup_info.dp_id = dp_id;
    lookup_info.value = p_sys_dot1ae_entry->is_cam[dp_id];
    drv_acc_get_hash_module(lchip,lookup_info.tbl_id, &lookup_info.module);
    /* write key table */
    CTC_ERROR_RETURN(drv_acc_api(lchip, &lookup_info, &lookup_result));

    if (p_sys_dot1ae_entry->is_cam[dp_id])
    {
        ad_tbl_id = (p_sys_dot1ae_entry->dir == CTC_INGRESS)? XSecRxCamAd_t : XSecTxCamAd_t;
    }
    else
    {
        ad_tbl_id = (p_sys_dot1ae_entry->dir == CTC_INGRESS)? XSecRxLookupAd_t : XSecTxLookupAd_t;
    }

    /* write ad table */
    cmd = DRV_IOR(ad_tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_dot1ae_entry->hash_key_index[dp_id], DRV_CMD_DP_EN(cmd, dp_id), &ds));
    SetDsXSec(V, cryptoSc_f, ds, p_sys_dot1ae_entry->sc_index[dp_id]);
    is_rx_plain = (p_sys_dot1ae_entry->key_type == CTC_DOT1AE_KEY_L2) && (p_sys_dot1ae_entry->dir == CTC_INGRESS);
    SetDsXSec(V, opType_f, ds, (is_remove || is_rx_plain)? SYS_DOT1AE_OP_TYPE_BYPASS : SYS_DOT1AE_OP_TYPE_PROCESS);
    is_mac_key = (p_sys_dot1ae_entry->key_type == CTC_DOT1AE_KEY_MACSEC)?1:0;
    SetDsXSec(V, offsetType_f, ds, _sys_at_dot1ae_clear_tag_mapping(lchip, 0,0,is_mac_key));
    cmd = DRV_IOW(ad_tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_dot1ae_entry->hash_key_index[dp_id], DRV_CMD_DP_EN(cmd, dp_id), &ds));

    return CTC_E_NONE;
}

int32 _sys_at_dot1ae_set_key_to_asic(uint8 lchip,sys_dot1ae_entry_t* p_sys_dot1ae_entry,uint32 hash_key[],uint8 is_remove,uint8 dp_id)
{
    /*1. Lookup hash key_index*/
    if (!is_remove)
    {
        CTC_ERROR_RETURN(_sys_at_dot1ae_build_key_index(lchip, p_sys_dot1ae_entry,hash_key,dp_id));
    }

    /*2. Add key&ad to asic*/
    CTC_ERROR_RETURN(sys_at_dot1ae_key_ad_write_io(lchip, p_sys_dot1ae_entry,hash_key,is_remove,dp_id));
    return CTC_E_NONE;
}


int32
_sys_at_dot1ae_show_entry_traverse(sys_dot1ae_entry_t* p_sys_entry,void* user_data)
{
    char value2str[2][10] = {{'-'},{'-'}};
    uint8 detail =0;
    uint16* num_ptr =0;
    uint8 hit =0;
    char* key_tbl_rx[CTC_DOT1AE_KEY_MAX] = {"\0","DsXSecRxL2BasicHashKey", "DsXSecRxL2MacsecHashKey","DsXSecRxL3L4V4HashKey","DsXSecRxL3L4V6HashKey","DsXSecRxSpiHashKey"};
    char* key_tbl_tx[CTC_DOT1AE_KEY_MAX] = {"\0","\0","DsXSecTxL2BasicHashKey","DsXSecTxL3L4V4HashKey","DsXSecTxL3L4V6HashKey","DsXSecTxSpiHashKey"};
    char* key_type_rx[CTC_DOT1AE_KEY_MAX] = {"\0","decrypt-l2-ext","decrypt-mac","decrypt-ipv4","decrypt-ipv6","decrypt-spi"};
    char* key_type_tx[CTC_DOT1AE_KEY_MAX] = {"\0","\0","encrypt-mac","encrypt-ipv4","encrypt-ipv6","encrypt-spi"};

    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = traversal_data->value1;
#endif
    sys_dot1ae_show_entry_info_t* entry_param = (sys_dot1ae_show_entry_info_t*)traversal_data->data;
    detail = traversal_data->value1;
    num_ptr = (uint16*)traversal_data->data1;
    if (entry_param->type == 0 || (entry_param->type == 1 && entry_param->entry_id == p_sys_entry->entry_id))
    {
        hit = 1;
    }

    if (entry_param->key_type != CTC_DOT1AE_KEY_MAX)
    {
        if (entry_param->key_type != p_sys_entry->key_type
            || entry_param->dir != p_sys_entry->dir)
        {
            hit =0;
        }
    }
    if (hit)
    {

        if (detail)
        {
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "#ENTRY_ID: 0x%X \n", p_sys_entry->entry_id);
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Table:\n");
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_entry->dp_bmp)
            if (p_sys_entry->is_cam[dp_idx])
            {
                SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-26s :0x%-6x dp%-2x\n",
                    (p_sys_entry->dir == CTC_EGRESS)?"DsXSecTxHashCam":"DsXSecRxHashCam", p_sys_entry->hash_key_index[dp_idx]/SYS_AT_DOT1AE_CAM_STEP,dp_idx);
            }
            else
            {
                SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-26s :0x%-6x dp%-2x\n",(p_sys_entry->dir == CTC_EGRESS)?key_tbl_tx[p_sys_entry->key_type]:key_tbl_rx[p_sys_entry->key_type], p_sys_entry->hash_key_index[dp_idx],dp_idx);
            }
            SYS_DOT1AE_FOREACH_DP_END
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Gport          :%-15u\n", p_sys_entry->gport);
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Sec-chan ID :%-15u\n", p_sys_entry->chan_id);

        }
        else
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_entry->dp_bmp)
            sal_sprintf(value2str[dp_idx], "0x%x", p_sys_entry->hash_key_index[dp_idx]);
            SYS_DOT1AE_FOREACH_DP_END
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-12u 0x%-10x %-14s %-14s %-14s\n", *num_ptr, p_sys_entry->entry_id, value2str[0],value2str[1], \
            (p_sys_entry->dir == CTC_EGRESS)? key_type_tx[p_sys_entry->key_type] : key_type_rx[p_sys_entry->key_type]);
        }
        (*num_ptr)++;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_chk_key_type(uint8 lchip,         uint8 key_type, ctc_field_key_t* key_field_list, uint32 field_cnt)
{
    uint32 macsec_key_cap[CTC_FIELD_KEY_NUM/CTC_UINT32_BITS] = {0};
    uint32 l2_key_cap[CTC_FIELD_KEY_NUM/CTC_UINT32_BITS] = {0};
    uint32 l3v4_key_cap[CTC_FIELD_KEY_NUM/CTC_UINT32_BITS] = {0};
    uint32 l3v6_key_cap[CTC_FIELD_KEY_NUM/CTC_UINT32_BITS] = {0};
    uint32 spi_key_cap[CTC_FIELD_KEY_NUM/CTC_UINT32_BITS] = {0};
    uint32 *key_cap_ptr = NULL;
    uint32 field_id = 0;
    uint8 key_type_match = 1;

    /* MACSC key field capability, DsXSecRxL2MacsecHashKey */
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_PORT);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_DOT1AE_SCI);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_STAG_VALID);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_SVLAN_ID);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_STAG_COS);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_CTAG_VALID);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_CVLAN_ID);
    CTC_BMP_SET(macsec_key_cap, CTC_FIELD_KEY_CTAG_COS);

    /* L2 basic key field capability, DsXSecTxL2BasicHashKey/DsXSecRxL2BasicHashKey */
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_PORT);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_MAC_DA);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_MAC_SA);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_STAG_VALID);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_STAG_COS);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_SVLAN_ID);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_CTAG_VALID);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_CVLAN_ID);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_CTAG_COS);
    CTC_BMP_SET(l2_key_cap, CTC_FIELD_KEY_ETHER_TYPE);

    /* L3 ipv4 key field capability, DsXSecTxL3L4V4HashKey/DsXSecRxL3L4V4HashKey */
    CTC_BMP_SET(l3v4_key_cap, CTC_FIELD_KEY_PORT);
    CTC_BMP_SET(l3v4_key_cap, CTC_FIELD_KEY_IP_SA);
    CTC_BMP_SET(l3v4_key_cap, CTC_FIELD_KEY_IP_DA);
    CTC_BMP_SET(l3v4_key_cap, CTC_FIELD_KEY_IP_PROTOCOL);
    CTC_BMP_SET(l3v4_key_cap, CTC_FIELD_KEY_L4_SRC_PORT);
    CTC_BMP_SET(l3v4_key_cap, CTC_FIELD_KEY_L4_DST_PORT);

    /* L3 ipv6 key field capability, DsXSecTxL3L4V6HashKey/DsXSecRxL3L4V6HashKey */
    CTC_BMP_SET(l3v6_key_cap, CTC_FIELD_KEY_PORT);
    CTC_BMP_SET(l3v6_key_cap, CTC_FIELD_KEY_IPV6_SA);
    CTC_BMP_SET(l3v6_key_cap, CTC_FIELD_KEY_IPV6_DA);
    CTC_BMP_SET(l3v6_key_cap, CTC_FIELD_KEY_IP_PROTOCOL);
    CTC_BMP_SET(l3v6_key_cap, CTC_FIELD_KEY_L4_SRC_PORT);
    CTC_BMP_SET(l3v6_key_cap, CTC_FIELD_KEY_L4_DST_PORT);

    /* spi key field capability, DsXSecTxSpiHashKey/DsXSecRxSpiHashKey */
    CTC_BMP_SET(spi_key_cap, CTC_FIELD_KEY_PORT);
    CTC_BMP_SET(spi_key_cap, CTC_FIELD_KEY_DOT1AE_SPI);

    /* check hash key capablity according to field list */
    key_cap_ptr = (SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC == key_type) ? l2_key_cap :\
                  (SYS_DOT1AE_HASH_KEY_TYPE_MACSEC == key_type) ? macsec_key_cap :\
                  (SYS_DOT1AE_HASH_KEY_TYPE_IPV4 == key_type) ? l3v4_key_cap :\
                  (SYS_DOT1AE_HASH_KEY_TYPE_IPV6 == key_type) ? l3v6_key_cap : spi_key_cap;
    for (field_id = 0; field_id < field_cnt; field_id ++)
    {
        key_type_match = (key_type_match && CTC_BMP_ISSET(key_cap_ptr, key_field_list[field_id].type));
    }

    return key_type_match ? CTC_E_NONE : CTC_E_INVALID_CONFIG;
}

STATIC int32
_sys_at_dot1ae_get_keytype_profile(uint8 lchip, uint8 pkt_type, uint8 dir, uint32* key_type_field, uint32* profile_field)
{
    uint32 pkt_type_map_key_type_rx[CTC_DOT1AE_PKT_MAX] = {0, XSecRxLookupDpCtl_keyType0_f,\
                                                           XSecRxLookupDpCtl_keyType5_f,\
                                                           XSecRxLookupDpCtl_keyType4_f,\
                                                           XSecRxLookupDpCtl_keyType9_f,\
                                                           XSecRxLookupDpCtl_keyType8_f,\
                                                           XSecRxLookupDpCtl_keyType7_f,\
                                                           XSecRxLookupDpCtl_keyType6_f,\
                                                           XSecRxLookupDpCtl_keyType11_f,\
                                                           XSecRxLookupDpCtl_keyType10_f,\
                                                           XSecRxLookupDpCtl_keyType1_f,\
                                                           XSecRxLookupDpCtl_keyType2_f,\
                                                           XSecRxLookupDpCtl_keyType3_f};
    uint32 pkt_type_map_key_type_tx[CTC_DOT1AE_PKT_MAX] = {0, XSecTxLookupDpCtl_keyType0_f,
                                                           0,\
                                                           0,\
                                                           0,\
                                                           0,\
                                                           XSecTxLookupDpCtl_keyType10_f,\
                                                           XSecTxLookupDpCtl_keyType10_f,\
                                                           XSecTxLookupDpCtl_keyType10_f,\
                                                           XSecTxLookupDpCtl_keyType10_f,\
                                                           XSecTxLookupDpCtl_keyType3_f,\
                                                           XSecTxLookupDpCtl_keyType4_f,\
                                                           XSecTxLookupDpCtl_keyType9_f};
    uint32 pkt_type_map_profile_rx[CTC_DOT1AE_PKT_MAX] = {0, XSecRxLookupChanCtl_array_11_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_1_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_0_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_5_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_4_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_3_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_2_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_7_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_6_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_12_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_13_maskProfileId_f,\
                                                          XSecRxLookupChanCtl_array_14_maskProfileId_f};
    uint32 pkt_type_map_profile_tx[CTC_DOT1AE_PKT_MAX] = {0, XSecTxLookupChanCtl_array_0_maskProfileId_f,
                                                           0,\
                                                           0,\
                                                           0,\
                                                           0,\
                                                           XSecTxLookupChanCtl_array_10_maskProfileId_f,\
                                                           XSecTxLookupChanCtl_array_10_maskProfileId_f,\
                                                           XSecTxLookupChanCtl_array_10_maskProfileId_f,\
                                                           XSecTxLookupChanCtl_array_10_maskProfileId_f,\
                                                           XSecTxLookupChanCtl_array_3_maskProfileId_f,\
                                                           XSecTxLookupChanCtl_array_4_maskProfileId_f,\
                                                           XSecTxLookupChanCtl_array_9_maskProfileId_f};

    if (key_type_field)
    {
        *key_type_field = (CTC_INGRESS == dir) ? pkt_type_map_key_type_rx[pkt_type] : pkt_type_map_key_type_tx[pkt_type];
    }

    if (profile_field)
    {
        *profile_field = (CTC_INGRESS == dir) ? pkt_type_map_profile_rx[pkt_type] : pkt_type_map_profile_tx[pkt_type];
    }

    return CTC_E_NONE;
}

STATIC uint32
_sys_at_dot1ae_build_maskbmp(uint8 lchip, uint8 key_type, uint8 dir, ctc_field_key_t* key_field_list, uint32 field_cnt)
{
    uint32 maskbmp = 0;
    uint16 field_id = 0;

    switch(key_type)
    {
        case SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC:
            for (field_id = 0 ; field_id < field_cnt ; field_id++)
            {
                if (CTC_FIELD_KEY_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 0);
                }
                else if (CTC_FIELD_KEY_MAC_DA == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 1);
                }
                else if (CTC_FIELD_KEY_MAC_SA == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 2);
                }
                else if (CTC_FIELD_KEY_STAG_VALID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 3);
                }
                else if (CTC_FIELD_KEY_SVLAN_ID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 4);
                }
                else if (CTC_FIELD_KEY_STAG_COS == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 5);
                }
                else if (CTC_FIELD_KEY_CTAG_VALID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 6);
                }
                else if (CTC_FIELD_KEY_CVLAN_ID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 7);
                }
                else if (CTC_FIELD_KEY_CTAG_COS == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 8);
                }
                else if (CTC_FIELD_KEY_ETHER_TYPE == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 9);
                }
            }
            break;
        case SYS_DOT1AE_HASH_KEY_TYPE_MACSEC:
            for (field_id = 0 ; field_id < field_cnt ; field_id++)
            {
                if (CTC_FIELD_KEY_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 0);
                }
                else if (CTC_FIELD_KEY_DOT1AE_SCI == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 1);
                }
                else if (CTC_FIELD_KEY_STAG_VALID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 2);
                }
                else if (CTC_FIELD_KEY_SVLAN_ID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 3);
                }
                else if (CTC_FIELD_KEY_STAG_COS == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 4);
                }
                else if (CTC_FIELD_KEY_CTAG_VALID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 5);
                }
                else if (CTC_FIELD_KEY_CVLAN_ID == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 6);
                }
                else if (CTC_FIELD_KEY_CTAG_COS == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 7);
                }
            }
            CTC_BIT_SET(maskbmp, 8);/* isMacsec */
            break;
        case SYS_DOT1AE_HASH_KEY_TYPE_IPV4:
            for (field_id = 0 ; field_id < field_cnt ; field_id++)
            {
                if (CTC_FIELD_KEY_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 0);
                }
                else if (CTC_FIELD_KEY_IP_DA == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 1);
                }
                else if (CTC_FIELD_KEY_IP_SA == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 2);
                }
                else if (CTC_FIELD_KEY_IP_PROTOCOL == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 3);
                }
                else if (CTC_FIELD_KEY_L4_DST_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 4);
                    if (CTC_INGRESS == dir)
                    {
                        CTC_BIT_SET(maskbmp, 6);/* ctcSecType */
                    }
                }
                else if (CTC_FIELD_KEY_L4_SRC_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 5);
                    if (CTC_INGRESS == dir)
                    {
                        CTC_BIT_SET(maskbmp, 6);/* ctcSecType */
                    }
                }
            }
            if (CTC_INGRESS == dir)
            {
                CTC_BIT_SET(maskbmp, 7);/* isCtcsec */
            }
            break;
        case SYS_DOT1AE_HASH_KEY_TYPE_IPV6:
            for (field_id = 0 ; field_id < field_cnt ; field_id++)
            {
                if (CTC_FIELD_KEY_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 0);
                }
                else if (CTC_FIELD_KEY_IPV6_DA == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 1);
                    if (CTC_INGRESS == dir)
                    {
                        CTC_BIT_SET(maskbmp, 8);/* ipDaExt, 16-bit ipv6-da */
                    }
                    else
                    {
                        CTC_BIT_SET(maskbmp, 6);/* ipDaExt, 16-bit ipv6-da */
                    }
                }
                else if (CTC_FIELD_KEY_IPV6_SA == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 2);
                    if (CTC_INGRESS == dir)
                    {
                        CTC_BIT_SET(maskbmp, 9);/* ipSaExt, 16-bit ipv6-sa */
                    }
                    else
                    {
                        CTC_BIT_SET(maskbmp, 7);/* ipSaExt, 16-bit ipv6-sa */
                    }
                }
                else if (CTC_FIELD_KEY_IP_PROTOCOL == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 3);
                }
                else if (CTC_FIELD_KEY_L4_DST_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 4);
                    if (CTC_INGRESS == dir)
                    {
                        CTC_BIT_SET(maskbmp, 6);/* ctcSecType */
                    }
                }
                else if (CTC_FIELD_KEY_L4_SRC_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 5);
                    if (CTC_INGRESS == dir)
                    {
                        CTC_BIT_SET(maskbmp, 6);/* ctcSecType */
                    }
                }
            }
            if (CTC_INGRESS == dir)
            {
                CTC_BIT_SET(maskbmp, 7);/* isCtcsec */
            }
            break;
        case SYS_DOT1AE_HASH_KEY_TYPE_SPI:
            for (field_id = 0 ; field_id < field_cnt ; field_id++)
            {
                if (CTC_FIELD_KEY_PORT == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 0);
                }
                else if (CTC_FIELD_KEY_DOT1AE_SPI == key_field_list[field_id].type)
                {
                    CTC_BIT_SET(maskbmp, 1);
                }
            }
            break;
         default:
            break;
    }

    return maskbmp;
}

STATIC int32
_sys_at_dot1ae_parser_maskbmp(uint8 lchip, uint8 key_type, ctc_field_key_t* key_field_list, ctc_dot1ae_hash_sel_t* p_hash_sel, uint32 maskbmp)
{
    uint32 field_id = 0;
    uint8 bit = 0;
    uint16 l2basic_bmp[SYS_AT_DOT1AE_MASKBMP_MSB] = {CTC_FIELD_KEY_PORT,\
                                                     CTC_FIELD_KEY_MAC_DA,\
                                                     CTC_FIELD_KEY_MAC_SA,\
                                                     CTC_FIELD_KEY_STAG_VALID,\
                                                     CTC_FIELD_KEY_SVLAN_ID,\
                                                     CTC_FIELD_KEY_STAG_COS,\
                                                     CTC_FIELD_KEY_CTAG_VALID,\
                                                     CTC_FIELD_KEY_CVLAN_ID,\
                                                     CTC_FIELD_KEY_CTAG_COS,\
                                                     CTC_FIELD_KEY_ETHER_TYPE};
    uint16 macsec_bmp[SYS_AT_DOT1AE_MASKBMP_MSB] = {CTC_FIELD_KEY_PORT,\
                                                    CTC_FIELD_KEY_DOT1AE_SCI,\
                                                    CTC_FIELD_KEY_STAG_VALID,\
                                                    CTC_FIELD_KEY_SVLAN_ID,\
                                                    CTC_FIELD_KEY_STAG_COS,\
                                                    CTC_FIELD_KEY_CTAG_VALID,\
                                                    CTC_FIELD_KEY_CVLAN_ID,\
                                                    CTC_FIELD_KEY_CTAG_COS};
    uint16 ipv4_bmp[SYS_AT_DOT1AE_MASKBMP_MSB] = {CTC_FIELD_KEY_PORT,\
                                                  CTC_FIELD_KEY_IP_DA,\
                                                  CTC_FIELD_KEY_IP_SA,\
                                                  CTC_FIELD_KEY_IP_PROTOCOL,\
                                                  CTC_FIELD_KEY_L4_DST_PORT,\
                                                  CTC_FIELD_KEY_L4_SRC_PORT};
    uint16 ipv6_bmp[SYS_AT_DOT1AE_MASKBMP_MSB] = {CTC_FIELD_KEY_PORT,\
                                                  CTC_FIELD_KEY_IPV6_DA,\
                                                  CTC_FIELD_KEY_IPV6_SA,\
                                                  CTC_FIELD_KEY_IP_PROTOCOL,\
                                                  CTC_FIELD_KEY_L4_DST_PORT,\
                                                  CTC_FIELD_KEY_L4_SRC_PORT};
    uint16 spi[SYS_AT_DOT1AE_MASKBMP_MSB] = {CTC_FIELD_KEY_PORT,\
                                             CTC_FIELD_KEY_DOT1AE_SPI};
    uint16 *bmp_ptr[SYS_DOT1AE_HASH_KEY_TYPE_MAX] = {NULL, l2basic_bmp, macsec_bmp, ipv4_bmp, ipv6_bmp, spi};

    for (bit = 0; bit < SYS_AT_DOT1AE_MASKBMP_MSB; bit++)
    {
        if (CTC_IS_BIT_SET(maskbmp, bit) && bmp_ptr[key_type][bit])
        {
            key_field_list[field_id++].type = bmp_ptr[key_type][bit];
        }
    }

    p_hash_sel->field_cnt = field_id;
    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_set_profileid(uint8 lchip, uint8 dir, uint32 sub_chan_id, uint32 dp_id, uint32 profile_field_id, uint32 profile_id)
{
    uint32 cmd = 0;
    ds_t ds;

    sal_memset(&ds, 0, sizeof(ds_t));

    if (CTC_EGRESS == dir)
    {
        cmd = DRV_IOR(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        if (XSecTxLookupChanCtl_array_0_maskProfileId_f == profile_field_id)
        {/* XSecTxLookupChanCtl.cryptoType = 0, for macsec */
            SetXSecTxLookupChanCtl(V, array_0_maskProfileId_f, &ds, profile_id);/* IPv4 Vxlan */
            SetXSecTxLookupChanCtl(V, array_1_maskProfileId_f, &ds, profile_id);/* IPv6 Vxlan */
            SetXSecTxLookupChanCtl(V, array_2_maskProfileId_f, &ds, profile_id);/* other */
        }
        else if (XSecTxLookupChanCtl_array_3_maskProfileId_f == profile_field_id)
        {/* XSecTxLookupChanCtl.cryptoType = 1, for ctcsec/cloudsec */
            SetXSecTxLookupChanCtl(V, array_3_maskProfileId_f, &ds, profile_id);/* IPv4 Vxlan */
            SetXSecTxLookupChanCtl(V, array_5_maskProfileId_f, &ds, profile_id);/* IPv4 GRE */
            SetXSecTxLookupChanCtl(V, array_7_maskProfileId_f, &ds, profile_id);/* IPv4 other */
            SetXSecTxLookupChanCtl(V, array_11_maskProfileId_f, &ds, profile_id);/* IPv4 UDP */
        }
        else if (XSecTxLookupChanCtl_array_4_maskProfileId_f == profile_field_id)
        {/* XSecTxLookupChanCtl.cryptoType = 1, for ctcsec/cloudsec */
            SetXSecTxLookupChanCtl(V, array_4_maskProfileId_f, &ds, profile_id);/* IPv6 Vxlan */
            SetXSecTxLookupChanCtl(V, array_6_maskProfileId_f, &ds, profile_id);/* IPv6 GRE */
            SetXSecTxLookupChanCtl(V, array_8_maskProfileId_f, &ds, profile_id);/* IPv6 other */
            SetXSecTxLookupChanCtl(V, array_12_maskProfileId_f, &ds, profile_id);/* IPv6 UDP */
        }
        else if (XSecTxLookupChanCtl_array_10_maskProfileId_f == profile_field_id)
        {/* XSecTxLookupChanCtl.cryptoType = 1, for SPI */
            SetXSecTxLookupChanCtl(V, array_10_maskProfileId_f, &ds, profile_id);/* SPI */
        }
        else
        {/* XSecTxLookupChanCtl.cryptoType = 1, for other */
            SetXSecTxLookupChanCtl(V, array_9_maskProfileId_f, &ds, profile_id);/* other */
        }
        cmd = DRV_IOW(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
    }
    else
    {
        cmd = DRV_IOW(XSecRxLookupChanCtl_t, profile_field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &profile_id));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_at_dot1ae_chk_glb_key_type(uint8 lchip, uint8 dir, uint8 packet_type, uint8 key_type)
{
    uint8 key_type_valid = 0;

    if (CTC_INGRESS == dir)
    {
        switch(packet_type)
        {
            case CTC_DOT1AE_PKT_MACSEC:
                /* for MACSEC p2mp decryption, port + SCI, so only support CTC_DOT1AE_KEY_MACSEC */
                key_type_valid = key_type == CTC_DOT1AE_KEY_MACSEC;
                break;
            case CTC_DOT1AE_PKT_CTCSEC_IPV4:
                key_type_valid = key_type == CTC_DOT1AE_KEY_IPV4;
                break;
            case CTC_DOT1AE_PKT_CTCSEC_IPV6:
                key_type_valid = key_type == CTC_DOT1AE_KEY_IPV6;
                break;
            case CTC_DOT1AE_PKT_CLOUDSEC_IPV4:
                key_type_valid = key_type == CTC_DOT1AE_KEY_IPV4;
                break;
            case CTC_DOT1AE_PKT_CLOUDSEC_IPV6:
                key_type_valid = key_type == CTC_DOT1AE_KEY_IPV6;
                break;
            case CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH:
            case CTC_DOT1AE_PKT_CLOUDSEC_IPV4_CTCSH:
                key_type_valid = (key_type == CTC_DOT1AE_KEY_SPI) || (key_type == CTC_DOT1AE_KEY_IPV4);
                break;
            case CTC_DOT1AE_PKT_CTCSEC_IPV6_CTCSH:
            case CTC_DOT1AE_PKT_CLOUDSEC_IPV6_CTCSH:
                key_type_valid = (key_type == CTC_DOT1AE_KEY_SPI) || key_type == CTC_DOT1AE_KEY_IPV6;
                break;
            case CTC_DOT1AE_PKT_IPV4:
                key_type_valid = key_type == CTC_DOT1AE_KEY_L2;
                break;
            case CTC_DOT1AE_PKT_IPV6:
                key_type_valid = key_type == CTC_DOT1AE_KEY_L2;
                break;
            case CTC_DOT1AE_PKT_OTHERS:
                key_type_valid = key_type == CTC_DOT1AE_KEY_L2;
                break;
            case CTC_DOT1AE_PKT_NONE:
                key_type_valid = TRUE;
            default :
                break;
        }
    }
    else
    {
        switch(packet_type)
        {
            case CTC_DOT1AE_PKT_MACSEC:
            case CTC_DOT1AE_PKT_OTHERS:
                /* for MACSEC p2mp encryption, port + SCI, so only support CTC_DOT1AE_KEY_MACSEC */
                key_type_valid = key_type == CTC_DOT1AE_KEY_MACSEC;
                break;
            case CTC_DOT1AE_PKT_IPV4:
            case CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH:
            case CTC_DOT1AE_PKT_CLOUDSEC_IPV4_CTCSH:
                key_type_valid = (key_type == CTC_DOT1AE_KEY_SPI) || (key_type == CTC_DOT1AE_KEY_IPV4);
                break;
            case CTC_DOT1AE_PKT_IPV6:
            case CTC_DOT1AE_PKT_CTCSEC_IPV6_CTCSH:
            case CTC_DOT1AE_PKT_CLOUDSEC_IPV6_CTCSH:
                key_type_valid = (key_type == CTC_DOT1AE_KEY_SPI) || (key_type == CTC_DOT1AE_KEY_IPV6);
                break;
            case CTC_DOT1AE_PKT_NONE:
                key_type_valid = TRUE;
            default :
                break;
        }
    }

    return key_type_valid ? CTC_E_NONE : CTC_E_INVALID_CONFIG;
}

#define __SYS_INTERFACE__

int32
sys_at_dot1ae_chan_wb_restore(uint8 lchip, void* p_chan)
{
    ds_t ds;
    sys_usw_opf_t opf;
    uint32 val_ary[2]={0};
    uint32  salt_hw[3];
    uint32 cmd = 0;
    uint8 hw_sci[SYS_DOT1AE_SCI_LEN]={0};
    uint32 tbl_id =0;
    uint16 key_index = 0;
    uint16 secYId = 0;
    uint8* p_key_hw = NULL;
    uint8 sa_idx = 0;
    uint8 is_xpn =0;
    uint8 field_id =0;

    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)p_chan;

    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    key_index = p_sys_chan->sc_index[dp_idx];
    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
    {
        cmd = DRV_IOR(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,  key_index , cmd, &ds));
        GetDsXSecEncryptSc(A, sci_f, &ds,hw_sci);
        is_xpn = GetDsXSecEncryptSc(V, isXpnMode_f, &ds);
        SYS_USW_SET_USER_VALUE(p_sys_chan->sci, (uint32*)hw_sci, SYS_DOT1AE_SCI_LEN);
    }
    else
    {
        cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,  key_index , cmd, &ds));
        GetDsXSecDecryptSc(A, sci_f, &ds,hw_sci);
        is_xpn = GetDsXSecDecryptSc(V, isXpnMode_f, &ds);
        SYS_USW_SET_USER_VALUE(p_sys_chan->sci, (uint32*)hw_sci, SYS_DOT1AE_SCI_LEN);

        tbl_id = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)? DsXSecEncryptScPre_t : DsXSecDecryptScPre_t;
        field_id = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)? DsXSecEncryptScPre_secYId_f : DsXSecDecryptScPre_secYId_f;
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_chan->sc_index[dp_idx], DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        secYId = DRV_GET_FIELD_V(lchip, tbl_id, field_id, &ds);

        cmd = DRV_IOR(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &ds));
        p_sys_chan->validateFrames = GetDsXSecDecryptSecY(V, validateFrames_f, &ds);
        p_sys_chan->replayProtect = GetDsXSecDecryptSecY(V, replayProtect_f, &ds);
        p_sys_chan->replayProtectWindow = GetDsXSecDecryptSecY(V, replayProtectWindow_f, &ds);
    }

    for (sa_idx = 0; sa_idx < 2; sa_idx++)
    {
        key_index = (p_sys_chan->sc_index[dp_idx] << 1) + (sa_idx & 0x1);
        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? DRV_IOR(DsXSecEncryptSaStatus_t, DRV_ENTRY_FLAG) : DRV_IOR(DsXSecDecryptSaStatus_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
        {
            GetDsXSecEncryptSaStatus(A, xpn_f, &ds, val_ary);
        }
        else
        {
            GetDsXSecDecryptSaStatus(A, nextPn_f, &ds, val_ary);
        }

        p_sys_chan->sa_cfg[sa_idx].next_pn = ((uint64)val_ary[1] << 32) | val_ary[0];
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
        {
            if (p_sys_chan->replayProtect)
            {
                if (p_sys_chan->sa_cfg[sa_idx].next_pn > p_sys_chan->replayProtectWindow)
                {
                    p_sys_chan->sa_cfg[sa_idx].lowest_pn = p_sys_chan->sa_cfg[sa_idx].next_pn - p_sys_chan->replayProtectWindow;
                }
            }
            else
            {
                p_sys_chan->sa_cfg[sa_idx].lowest_pn = p_sys_chan->sa_cfg[sa_idx].next_pn;
            }
        }
        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOR(DsXSecDecryptSa_t, DRV_ENTRY_FLAG):
        DRV_IOR(DsXSecEncryptSaPre_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
        {
            p_sys_chan->sa_cfg[sa_idx].cipher_mode = GetDsXSecDecryptSa(V, u_gSecY_cipherMode_f, &ds);
            p_sys_chan->sa_cfg[sa_idx].cipher_suite = is_xpn<<1 | GetDsXSecDecryptSa(V, keyLenType_f, &ds);
            sal_memset(salt_hw, 0, sizeof(salt_hw));
            GetDsXSecDecryptSa(A, u_gSecY_salt_f, &ds, salt_hw);
            SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].salt, salt_hw, sizeof(salt_hw));
            p_sys_chan->sa_cfg[sa_idx].ssci = GetDsXSecDecryptSa(V, u_gSecY_ssci_f, &ds);
            p_key_hw = mem_malloc(MEM_DOT1AE_MODULE, CTC_DOT1AE_KEY_LEN);
            if (NULL == p_key_hw)
            {
                return CTC_E_NO_MEMORY;
            }
            sal_memset(p_key_hw, 0 , CTC_DOT1AE_KEY_LEN);
            if ((CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite) || (CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite))
            {
                GetDsXSecDecryptSa(A, decryptKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN / 2);
            }
            else
            {
                GetDsXSecDecryptSa(A, decryptKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN);
            }
            mem_free(p_key_hw);
        }
        else
        {
            sal_memset(salt_hw, 0, sizeof(salt_hw));
            p_sys_chan->sa_cfg[sa_idx].cipher_mode = GetDsXSecEncryptSaPre(V, u_gSecY_cipherMode_f, &ds);

            cmd = DRV_IOR(DsXSecEncryptSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
            p_sys_chan->sa_cfg[sa_idx].cipher_suite = is_xpn<<1 | GetDsXSecEncryptSa(V, keyLenType_f, &ds);
            GetDsXSecEncryptSa(A, u_gSecY_salt_f, &ds, salt_hw);
            SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].salt, salt_hw, sizeof(salt_hw));
            p_sys_chan->sa_cfg[sa_idx].ssci = GetDsXSecEncryptSa(V, u_gSecY_ssci_f, &ds);
            p_key_hw = mem_malloc(MEM_DOT1AE_MODULE, CTC_DOT1AE_KEY_LEN);
            if (NULL == p_key_hw)
            {
                return CTC_E_NO_MEMORY;
            }
            sal_memset(p_key_hw, 0 , CTC_DOT1AE_KEY_LEN);
            if ((CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite) || (CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite))
            {
                GetDsXSecEncryptSa(A, encryptKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN / 2);
            }
            else
            {
                GetDsXSecEncryptSa(A, encryptKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN);
            }
            mem_free(p_key_hw);
        }

        if (0 != p_sys_chan->binding_type)
        {
            p_sys_chan->sa_cfg[sa_idx].no_encryption = (p_sys_chan->sa_cfg[sa_idx].cipher_mode == 5 )? 1 : 0;
        }
        else
        {
            p_sys_chan->sa_cfg[sa_idx].no_encryption = (p_sys_chan->sa_cfg[sa_idx].cipher_mode == 3 )? 1 : 0;
        }
    }

    sal_memset(&opf,0,sizeof(sys_usw_opf_t));
    /*recover opf*/
    if (p_sys_chan->binded&&!p_sys_chan->is_use_plain)
    {
        opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
        opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_sys_chan->sc_index[dp_idx]));
    }
    SYS_DOT1AE_FOREACH_DP_END



    return CTC_E_NONE;
}



int32
sys_at_dot1ae_set_chan_ctl(uint8 lchip, void* sys_chan)
{
    uint32 cmd = 0;
    uint32 sub_chan_id = 0;
    ds_t ds;
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;
    uint8 dp_id = p_sys_chan->dp_id;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    dmps_port_info.gport = p_sys_chan->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
    if (CTC_DOT1AE_SC_DIR_RX == p_sys_chan->dir)
    {
        cmd = DRV_IOR(XSecRxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
        {/* MACSEC p2p use opType and cryptoSc on chan */
            SetXSecRxLookupChanCtl(V, opType_f, &ds, SYS_DOT1AE_OP_TYPE_PROCESS);
            SetXSecRxLookupChanCtl(V, cryptoSc_f, &ds, p_sys_chan->sc_index[dp_id]);
        }
        else if (p_sys_chan->p2mp)
        {/* MACSEC p2mp use opType to discard, when hash looking up not match */
            SetXSecRxLookupChanCtl(V, opType_f, &ds, SYS_DOT1AE_OP_TYPE_DISCARD);
        }
        cmd = DRV_IOW(XSecRxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
    }
    else
    {

        cmd = DRV_IOR(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, p_sys_chan->dp_id), &ds));
        if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
        {/* MACSEC p2p use opType and cryptoSc on chan */
            SetXSecTxLookupChanCtl(V, opType_f, &ds, SYS_DOT1AE_OP_TYPE_PROCESS);
            SetXSecTxLookupChanCtl(V, cryptoSc_f, &ds, p_sys_chan->sc_index[dp_id]);
            SetXSecTxLookupChanCtl(V, offsetType_f, &ds, SYS_DOT1AE_SEGTAG_OFFSET_L2_OFFSET);
        }
        cmd = DRV_IOW(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
    }

    return CTC_E_NONE;
}


int32
sys_at_dot1ae_update_sec_chan(uint8 lchip, void* sys_chan, void* sc)
{
    sys_dot1ae_chan_t* p_sys_sec_chan = (sys_dot1ae_chan_t*)sys_chan;
    ctc_dot1ae_sc_t* p_sc = (ctc_dot1ae_sc_t*)sc;
    int32  ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 sci_hw[2] = {0};
    uint16 secYId = 0;
    uint16 sc_index = 0;
    ds_t ds;

    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_sc->property)
    {
    case CTC_DOT1AE_SC_PROP_AN_EN:
        ret = _sys_at_dot1ae_update_sec_chan_an_en(lchip,p_sys_sec_chan, p_sc->data);
        break;
    case CTC_DOT1AE_SC_PROP_INCLUDE_SCI:
        p_sys_sec_chan->include_sci=  p_sc->data ? 1: 0;

        if (p_sys_sec_chan->binded)
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            sc_index = p_sys_sec_chan->sc_index[dp_idx];
            secYId = sys_at_dot1ae_get_secyid(lchip, p_sc->chan_id, dp_idx);
            cmd = DRV_IOR(DsXSecEncryptSecYPre_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            SetDsXSecEncryptSecYPre(V, alwaysIncludeSci_f, &ds, p_sys_sec_chan->include_sci);
            cmd = DRV_IOW(DsXSecEncryptSecYPre_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            SYS_DOT1AE_FOREACH_DP_END

        }
        break;
    case CTC_DOT1AE_SC_PROP_SCI :
        SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)p_sc->ext_data, sizeof(sci_hw));
        if (p_sys_sec_chan->p2mp && (p_sys_sec_chan->binded))
        {
            return CTC_E_IN_USE;
        }
        else if (p_sys_sec_chan->binded)
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            sc_index = p_sys_sec_chan->sc_index[dp_idx];
            if (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX)
            {
                cmd = DRV_IOR(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecEncryptSc(A, sci_f, &ds, sci_hw);
                cmd = DRV_IOW(DsXSecEncryptSc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            }
            else
            {
                cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecDecryptSc(A, sci_f, &ds, sci_hw);
                cmd = DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            }
            SYS_DOT1AE_FOREACH_DP_END
        }
        if (p_sys_sec_chan->sci)
        {
            sal_memcpy(p_sys_sec_chan->sci, (uint8*)p_sc->ext_data, SYS_DOT1AE_SCI_LEN);
        }
        break;
    case CTC_DOT1AE_SC_PROP_REPLAY_WINDOW_SIZE :
        p_sys_sec_chan->replayProtectWindow = p_sc->data;
        if (p_sys_sec_chan->binded)
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            secYId = sys_at_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
            cmd = DRV_IOR(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            SetDsXSecDecryptSecY(V, replayProtectWindow_f, &ds, p_sys_sec_chan->replayProtectWindow);
            cmd = DRV_IOW(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            SYS_DOT1AE_FOREACH_DP_END
        }
        break;
    case CTC_DOT1AE_SC_PROP_REPLAY_PROTECT_EN:
        p_sys_sec_chan->replayProtect = p_sc->data? 1 : 0;
        if (p_sys_sec_chan->binded)
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            secYId = sys_at_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
            cmd = DRV_IOR(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            SetDsXSecDecryptSecY(V, replayProtect_f, &ds, p_sys_sec_chan->replayProtect);
            cmd = DRV_IOW(DsXSecDecryptSecY_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            SYS_DOT1AE_FOREACH_DP_END
        }
        break;

    case CTC_DOT1AE_SC_PROP_PROTOCOL_MODE:
        p_sys_sec_chan->protocol_type = p_sc->data;

        if (p_sys_sec_chan->binded)
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            if (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)
            {
                sc_index = p_sys_sec_chan->sc_index[dp_idx];
                cmd = DRV_IOR(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecDecryptSc(V, compatibleMode_f, &ds, (p_sc->data? 1 : 0));
                cmd = DRV_IOW(DsXSecDecryptSc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            }
            else
            {
                secYId = sys_at_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
                cmd = DRV_IOR(DsXSecEncryptSecY_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
                SetDsXSecEncryptSecY(V, secYEtherTypeProfileId_f, &ds, (p_sys_sec_chan->protocol_type?2:0));
                cmd = DRV_IOW(DsXSecEncryptSecY_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
            }
            SYS_DOT1AE_FOREACH_DP_END
        }
        break;

    default :
        break;
     }

    return ret;
}

int32
sys_at_dot1ae_unbind_sec_chan(uint8 lchip, void* bind_sc)
{
    sys_traverse_t user_data;
    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.data =  (void*)bind_sc;
    user_data.value1 = lchip;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_at_dot1ae_unbind_traverse, (void *)&user_data));
    return CTC_E_NONE;
}


int32
sys_at_dot1ae_get_en_sec_chan(uint8 lchip, void* bind_sc)
{
    uint32 xsec_en_bmp = 0;
    uint32 sub_chan_id = 0;
    uint32 cmd = 0;
    int32 ret =0;
    uint32 port_id =0;
    uint32 dp_id = 0;
    sys_com_dot1ae_bind_sc_t* p_bind_sc = (sys_com_dot1ae_bind_sc_t*)bind_sc;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)bind_sc;
    SYS_DOT1AE_INIT_CHECK(lchip);
    if (!SYS_GPORT_IS_NETWORK_PORT(p_bind_sc->gport)|| SYS_USW_DOT1AE_GPORT_IS_REMOTE(lchip,p_bind_sc->gport))
    {
        return CTC_E_INVALID_CONFIG;
    }
    SYS_DOT1AE_LOCK(lchip);

    dmps_port_info.gport = p_bind_sc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
     _sys_at_dot1ae_map_chanid_portid(lchip,p_bind_sc->dir,dp_id,sub_chan_id,&port_id);
    SYS_DOT1AE_GET_DP_ID(lchip, p_bind_sc->gport, dp_id);

    if (CTC_DOT1AE_SC_DIR_RX == p_bind_sc->dir)
    {
        cmd = DRV_IOR(NetRxXSecChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds), ret, err);
        xsec_en_bmp = GetNetRxXSecChanCtl(V, xSecEn_f, &ds);
        p_bind_sc->dot1AE_RX_En = CTC_IS_BIT_SET(xsec_en_bmp, port_id);
    }
    else
    {
        cmd = DRV_IOR(EpeScheduleXSecEncPortEnable_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds), ret, err);
        xsec_en_bmp = GetEpeScheduleXSecEncPortEnable(V, cfgPortEnableXSecEncBmp_f, &ds);
        p_bind_sc->dot1AE_TX_En = CTC_IS_BIT_SET(xsec_en_bmp, port_id);
    }
    p_bind_sc->enable = p_bind_sc->dot1AE_RX_En || p_bind_sc->dot1AE_TX_En;
err:
    SYS_DOT1AE_UNLOCK(lchip);
    return ret;

}

int32
sys_at_dot1ae_en_sec_chan(uint8 lchip, void* bind_sc)
{
    uint32 xsec_en_bmp = 0;
    uint32 sub_chan_id = 0;
    uint32 cmd = 0;
    int32 ret =0;
    uint32 port_id = 0;
    uint32 dp_id = 0;
    sys_com_dot1ae_bind_sc_t* p_bind_sc = (sys_com_dot1ae_bind_sc_t*)bind_sc;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)bind_sc;
    SYS_DOT1AE_INIT_CHECK(lchip);
    if (!SYS_GPORT_IS_NETWORK_PORT(p_bind_sc->gport) || SYS_USW_DOT1AE_GPORT_IS_REMOTE(lchip,p_bind_sc->gport))
    {
        return CTC_E_INVALID_CONFIG;
    }
    SYS_DOT1AE_LOCK(lchip);

    dmps_port_info.gport = p_bind_sc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
    SYS_DOT1AE_GET_DP_ID(lchip, p_bind_sc->gport, dp_id);
    _sys_at_dot1ae_map_chanid_portid(lchip,p_bind_sc->dir,dp_id,sub_chan_id,&port_id);

    if (CTC_DOT1AE_SC_DIR_RX == p_bind_sc->dir)
    {
        cmd = DRV_IOR(NetRxXSecChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds), ret, err);
        xsec_en_bmp = GetNetRxXSecChanCtl(V, xSecEn_f, &ds);
        p_bind_sc->dot1AE_RX_En ? CTC_BIT_SET(xsec_en_bmp, port_id) : CTC_BIT_UNSET(xsec_en_bmp, port_id);
        SetNetRxXSecChanCtl(V, xSecEn_f, &ds, xsec_en_bmp);
        cmd = DRV_IOW(NetRxXSecChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds), ret, err);
    }
    else
    {
        cmd = DRV_IOR(EpeScheduleXSecEncPortEnable_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds), ret, err);
        xsec_en_bmp = GetEpeScheduleXSecEncPortEnable(V, cfgPortEnableXSecEncBmp_f, &ds);
        p_bind_sc->dot1AE_TX_En ? CTC_BIT_SET(xsec_en_bmp, port_id) : CTC_BIT_UNSET(xsec_en_bmp, port_id);
        SetEpeScheduleXSecEncPortEnable(V, cfgPortEnableXSecEncBmp_f, &ds, xsec_en_bmp);
        cmd = DRV_IOW(EpeScheduleXSecEncPortEnable_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds), ret, err);
    }
err:
    SYS_DOT1AE_UNLOCK(lchip);
    return ret;
}

int32
sys_at_dot1ae_get_stats(uint8 lchip, uint32 chan_id, void* stats)
{
    uint16 secYId = 0;
    uint32  cmd = 0;
    sys_dot1ae_chan_t* p_chan = NULL;
    uint32 sc_index =0;
    uint32 val_ary[2]={0};
    ds_t ds;
    ctc_dot1ae_stats_t* p_stats = (ctc_dot1ae_stats_t*)stats;
    sys_at_dot1ae_an_stats_t* p_sys_stats = NULL;

    SYS_DOT1AE_INIT_CHECK(lchip);
    p_chan = _sys_usw_dot1ae_chan_lookup(lchip, chan_id);
    if (p_chan == NULL)
    {
        return CTC_E_NOT_EXIST;
    }

    if (p_chan->binded == 0)
    {
        return CTC_E_NONE;
    }

    p_sys_stats = (sys_at_dot1ae_an_stats_t*)(p_chan->an_stats);
    if (p_chan->is_use_plain)
    {
        return CTC_E_NONE;
    }
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_chan->dp_bmp)
    secYId = sys_at_dot1ae_get_secyid(lchip, chan_id,dp_idx);
    sc_index = p_chan->sc_index[dp_idx];

    if (p_chan->dir == CTC_DOT1AE_SC_DIR_RX )
    {
        cmd = DRV_IOR(DsXSecRxSecYStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        GetDsXSecRxSecYStats(A, array_0_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_badtag += ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxSecYStats(A, array_2_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_not_using_sa +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxSecYStats(A, array_1_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_unused_sa += ((uint64)val_ary[1] << 32) | val_ary[0];

        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecRxSecYStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        }
        cmd = DRV_IOR(DsXSecRxScStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        GetDsXSecRxScStats(A, array_5_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_ok +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxScStats(A, array_4_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_unchecked += ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxScStats(A, array_3_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_delayed+= ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxScStats(A, array_0_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_late +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxScStats(A, array_2_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_invalid +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecRxScStats(A, array_1_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].in_pkts_not_valid +=   ((uint64)val_ary[1] << 32) | val_ary[0];
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecRxScStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        }

        cmd = DRV_IOR(DsXSecRxSecYByteStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));

        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsXSecRxSecYByteStats(A, array_0_byteCount_f, &ds, val_ary);
        p_stats->an_stats[0].in_octets_decrypted += ((uint64)val_ary[1] << 32) | val_ary[0];
        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsXSecRxSecYByteStats(A, array_1_byteCount_f, &ds, val_ary);
        p_stats->an_stats[0].in_octets_validated += ((uint64)val_ary[1] << 32) | val_ary[0];

        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecRxSecYByteStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        }

    }
    else
    {
        cmd = DRV_IOR(DsXSecTxSecYStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        GetDsXSecTxSecYStats(A, array_1_packetCount_f, &ds, val_ary);
        p_stats->an_stats[0].out_pkts_untagged += ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecTxSecYStats(A, array_2_packetCount_f, &ds, val_ary);
        p_stats->an_stats[0].out_pkts_toolong +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecTxSecYStats(A, array_0_packetCount_f, &ds, val_ary);
        p_stats->an_stats[0].out_pkts_uncontrol_port +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecTxSecYStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        }

        cmd = DRV_IOR(DsXSecTxScStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        GetDsXSecTxScStats(A, array_2_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].out_pkts_encrypted += ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecTxScStats(A, array_1_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].out_pkts_protected +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        GetDsXSecTxScStats(A, array_0_packetCount_f, &ds,val_ary);
        p_stats->an_stats[0].out_pkts_sa_not_inuse +=  ((uint64)val_ary[1] << 32) | val_ary[0];
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecTxScStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        }
        cmd = DRV_IOR(DsXSecTxSecYByteStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));

        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsXSecTxSecYByteStats(A, array_1_byteCount_f, &ds, val_ary);
        p_stats->an_stats[0].out_octets_encrypted += ((uint64)val_ary[1] << 32) | val_ary[0];
        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsXSecTxSecYByteStats(A, array_0_byteCount_f, &ds, val_ary);
        p_stats->an_stats[0].out_octets_protected += ((uint64)val_ary[1] << 32) | val_ary[0];

        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecTxSecYByteStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, DRV_CMD_DP_EN(cmd, dp_idx), &ds));
        }
    }
    SYS_DOT1AE_FOREACH_DP_END

    p_stats->an_stats[0].out_pkts_protected += p_sys_stats[0].out_pkts_protected;
    p_stats->an_stats[0].out_pkts_encrypted += p_sys_stats[0].out_pkts_encrypted;
    p_stats->an_stats[0].in_pkts_ok += p_sys_stats[0].in_pkts_ok;
    p_stats->an_stats[0].in_pkts_unchecked += p_sys_stats[0].in_pkts_unchecked;
    p_stats->an_stats[0].in_pkts_delayed += p_sys_stats[0].in_pkts_delayed;
    p_stats->an_stats[0].in_pkts_invalid += p_sys_stats[0].in_pkts_invalid;
    p_stats->an_stats[0].in_pkts_not_valid += p_sys_stats[0].in_pkts_not_valid;
    p_stats->an_stats[0].in_pkts_late += p_sys_stats[0].in_pkts_late;
    p_stats->an_stats[0].in_pkts_not_using_sa += p_sys_stats[0].in_pkts_not_using_sa;
    p_stats->an_stats[0].in_pkts_unused_sa += p_sys_stats[0].in_pkts_unused_sa;

    p_stats->an_stats[0].in_pkts_badtag +=  p_sys_stats[0].in_pkts_badtag;
    p_stats->an_stats[0].in_octets_decrypted +=  p_sys_stats[0].in_octets_decrypted;
    p_stats->an_stats[0].in_octets_validated +=  p_sys_stats[0].in_octets_validated;
    p_stats->an_stats[0].out_pkts_untagged +=  p_sys_stats[0].out_pkts_untagged;
    p_stats->an_stats[0].out_pkts_toolong +=  p_sys_stats[0].out_pkts_toolong;
    p_stats->an_stats[0].out_pkts_sa_not_inuse +=  p_sys_stats[0].out_pkts_sa_not_inuse;
    p_stats->an_stats[0].out_octets_encrypted +=  p_sys_stats[0].out_octets_encrypted;
    p_stats->an_stats[0].out_octets_protected +=  p_sys_stats[0].out_octets_protected;

    p_sys_stats[0].out_pkts_protected = p_stats->an_stats[0].out_pkts_protected;
    p_sys_stats[0].out_pkts_encrypted = p_stats->an_stats[0].out_pkts_encrypted;
    p_sys_stats[0].in_pkts_ok = p_stats->an_stats[0].in_pkts_ok;
    p_sys_stats[0].in_pkts_unchecked = p_stats->an_stats[0].in_pkts_unchecked;
    p_sys_stats[0].in_pkts_delayed = p_stats->an_stats[0].in_pkts_delayed;
    p_sys_stats[0].in_pkts_invalid = p_stats->an_stats[0].in_pkts_invalid;
    p_sys_stats[0].in_pkts_not_valid = p_stats->an_stats[0].in_pkts_not_valid;
    p_sys_stats[0].in_pkts_late = p_stats->an_stats[0].in_pkts_late;
    p_sys_stats[0].in_pkts_not_using_sa = p_stats->an_stats[0].in_pkts_not_using_sa;
    p_sys_stats[0].in_pkts_unused_sa = p_stats->an_stats[0].in_pkts_unused_sa;

    p_sys_stats[0].in_pkts_badtag =  p_stats->an_stats[0].in_pkts_badtag ;
    p_sys_stats[0].in_octets_decrypted = p_stats->an_stats[0].in_octets_decrypted ;
    p_sys_stats[0].in_octets_validated = p_stats->an_stats[0].in_octets_validated ;
    p_sys_stats[0].out_pkts_untagged = p_stats->an_stats[0].out_pkts_untagged ;
    p_sys_stats[0].out_pkts_toolong = p_stats->an_stats[0].out_pkts_toolong ;
    p_sys_stats[0].out_pkts_sa_not_inuse = p_stats->an_stats[0].out_pkts_sa_not_inuse ;
    p_sys_stats[0].out_octets_encrypted = p_stats->an_stats[0].out_octets_encrypted ;
    p_sys_stats[0].out_octets_protected = p_stats->an_stats[0].out_octets_protected ;

    if (p_chan->p2mp)
    {/* get p2mp secy stats by port, set to 0 here. */
        p_stats->an_stats[0].in_pkts_badtag = 0;
        p_stats->an_stats[0].in_octets_decrypted = 0;
        p_stats->an_stats[0].in_octets_validated = 0;
        p_stats->an_stats[0].out_pkts_untagged = 0;
        p_stats->an_stats[0].out_pkts_toolong = 0;
        p_stats->an_stats[0].in_pkts_not_using_sa = 0;
        p_stats->an_stats[0].in_pkts_unused_sa = 0;
        p_stats->an_stats[0].out_octets_encrypted = 0;
        p_stats->an_stats[0].out_octets_protected = 0;
        p_stats->an_stats[0].out_pkts_uncontrol_port = 0;
    }

    return CTC_E_NONE;
}


int32
sys_at_dot1ae_get_secy_stats(uint8 lchip, uint32 gport, uint8 dir, void* p_stats)
{
    ds_t ds;
    sys_traverse_t user_data;
    ctc_dot1ae_an_stats_t* p_secy_stats =(ctc_dot1ae_an_stats_t*)p_stats;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    uint32  cmd = 0;
    uint32 val_ary[2]={0};
    uint32 sub_chan_id = 0;
    uint32 dp_id = 0;

    SYS_DOT1AE_INIT_CHECK(lchip);

    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.value1 = gport;
    user_data.value2 = dir;
    user_data.value3 = lchip;
    user_data.data =  p_secy_stats;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_at_get_secy_stats_traverse, (void *)&user_data));

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &dp_id));

    if (dir == CTC_DOT1AE_SC_DIR_RX)
    {
        cmd = DRV_IOR(DsXSecRxChanStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsXSecRxChanStats(A, array_1_packetCount_f, &ds, val_ary);
        p_secy_stats->in_pkts_discard = ((uint64)val_ary[1] << 32) | val_ary[0];
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecRxChanStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        }
    }
    else
    {
        cmd = DRV_IOR(DsXSecTxChanStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsXSecTxChanStats(A, array_1_packetCount_f, &ds, val_ary);
        p_secy_stats->out_pkts_discard = ((uint64)val_ary[1] << 32) | val_ary[0];
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOW(DsXSecTxChanStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        }
    }


    return CTC_E_NONE;
}

int32
sys_at_dot1ae_sync_dma_stats(uint8 lchip, void* p_data)
{
    uint8 type = 0;
    uint32* p_addr = NULL;
    sys_traverse_t user_data;
    sys_dma_reg_t* p_dma_reg = (sys_dma_reg_t*)p_data;
    type = *((uint8*)p_dma_reg->p_ext);
    p_addr = p_dma_reg->p_data;
    sal_memset(&user_data, 0 ,sizeof(sys_traverse_t));
    user_data.value2 = type;
    user_data.data = (void*)p_addr;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_at_dot1ae_sync_dma_traverse, (void *)&user_data));
    return CTC_E_NONE;
}

int32 sys_at_dot1ae_get_glb_cfg(uint8 lchip, void* glb_cfg)
{
    uint32 cmd = 0;
    ds_t ds;
    ds_t ds1;
    uint32 val_ary_tx[2]={0};
    uint32 val_ary_rx[2]={0};
    ctc_dot1ae_glb_cfg_t*  p_glb_cfg = (ctc_dot1ae_glb_cfg_t*)glb_cfg;
    uint32 key_type_field = 0;
    uint32 key_type = 0;

    p_glb_cfg->is_xpn = usw_dot1ae_master[lchip]->is_xpn;
    cmd = DRV_IOR(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 0), &ds));
    cmd = DRV_IOR(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 0), &ds1));

    p_glb_cfg->algorithm_type =GetXSecRxDecryptDpCtl(V, dpDecryptType_f, &ds);

    GetXSecRxDecryptDpCtl(A, xpnThreshold0_f, &ds, val_ary_rx);
    GetXSecTxEncryptDpCtl(A, xpnThreshold0_f, &ds1, val_ary_tx);
    p_glb_cfg->rx_xpn_thrd = ((uint64)val_ary_rx[1] << 32) | val_ary_rx[0];
    p_glb_cfg->tx_xpn_thrd = ((uint64)val_ary_tx[1] << 32) | val_ary_tx[0];

    p_glb_cfg->rx_pn_thrd = GetXSecRxDecryptDpCtl(V, pnThreshold0_f, &ds);
    p_glb_cfg->tx_pn_thrd = GetXSecTxEncryptDpCtl(V, pnThreshold0_f, &ds1);


    p_glb_cfg->ctc_sh_mode = (GetXSecTxEncryptDpCtl(V, array_0_strangeFieldSelect_f, &ds1) != 0)? 1 : 0;

    /* decryption key type config */
    if (CTC_INGRESS == p_glb_cfg->key_type.dir)
    {
        _sys_at_dot1ae_get_keytype_profile(lchip, p_glb_cfg->key_type.packet_type, CTC_INGRESS, &key_type_field, NULL);
        cmd = DRV_IOR(XSecRxLookupDpCtl_t, key_type_field);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 0), &key_type));
        p_glb_cfg->key_type.key_type = key_type;
    }
    else
    {
        /* encryption key type config */
        cmd = DRV_IOR(XSecTxLookupDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 0), &ds1));
        if (CTC_DOT1AE_PKT_MACSEC == p_glb_cfg->key_type.packet_type)
        {
            p_glb_cfg->key_type.key_type = GetXSecTxLookupDpCtl(V, keyType0_f, &ds1);
        }
        else if (CTC_DOT1AE_PKT_IPV4 == p_glb_cfg->key_type.packet_type)
        {
            p_glb_cfg->key_type.key_type = GetXSecTxLookupDpCtl(V, keyType3_f, &ds1);
        }
        else if (CTC_DOT1AE_PKT_IPV6 == p_glb_cfg->key_type.packet_type)
        {
            p_glb_cfg->key_type.key_type = GetXSecTxLookupDpCtl(V, keyType4_f, &ds1);
        }
        else if (CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH == p_glb_cfg->key_type.packet_type ||\
                 CTC_DOT1AE_PKT_CLOUDSEC_IPV4_CTCSH == p_glb_cfg->key_type.packet_type ||\
                 CTC_DOT1AE_PKT_CTCSEC_IPV6_CTCSH == p_glb_cfg->key_type.packet_type ||\
                 CTC_DOT1AE_PKT_CLOUDSEC_IPV6_CTCSH == p_glb_cfg->key_type.packet_type)
        {
            p_glb_cfg->key_type.key_type = GetXSecTxLookupDpCtl(V, keyType10_f, &ds1);
        }
        else if (CTC_DOT1AE_PKT_OTHERS == p_glb_cfg->key_type.packet_type)
        {
            p_glb_cfg->key_type.key_type = GetXSecTxLookupDpCtl(V, keyType9_f, &ds1);
        }
        if (SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC == p_glb_cfg->key_type.key_type)
        {
            p_glb_cfg->key_type.key_type = CTC_DOT1AE_KEY_MACSEC;
        }
    }

    return CTC_E_NONE;
}

int32 sys_at_dot1ae_set_glb_cfg(uint8 lchip, void* glb_cfg)
{
    uint32 cmd = 0;
    ds_t ds;
    ds_t ds1;
    uint32 dp_id = 0;
    uint8 index = 0;
    uint8 max_sec_type = 4;
    uint32 val_ary_tx[2]={0};
    uint32 val_ary_rx[2]={0};
    uint32 shim_mask[2]={0xFFFF00FF,0xFFFF};
    uint32 key_type_field = 0;
    uint32 key_type = 0;
    ctc_dot1ae_glb_cfg_t*  p_glb_cfg = (ctc_dot1ae_glb_cfg_t*)glb_cfg;

    /* 1. check global key type config */
    CTC_ERROR_RETURN(_sys_at_dot1ae_chk_glb_key_type(lchip, p_glb_cfg->key_type.dir, p_glb_cfg->key_type.packet_type, p_glb_cfg->key_type.key_type));

    /* 2. set global xpn mode */
    _sys_at_dot1ae_update_global_pn_mode(lchip, usw_dot1ae_master[lchip]->is_xpn);

    for (dp_id = 0; dp_id < 2 ;dp_id++)
    {
        /* 3.set pn/xpn threshold */
        cmd = DRV_IOR(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        cmd = DRV_IOR(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds1));

        val_ary_tx[0] = p_glb_cfg->tx_xpn_thrd&0xFFFFFFFF;
        val_ary_tx[1] = (p_glb_cfg->tx_xpn_thrd >> 32)&0xFFFFFFFF;
        SetXSecTxEncryptDpCtl(A, xpnThreshold0_f, &ds1, val_ary_tx);
        val_ary_rx[0] = p_glb_cfg->rx_xpn_thrd&0xFFFFFFFF;
        val_ary_rx[1] = (p_glb_cfg->rx_xpn_thrd >> 32)&0xFFFFFFFF;
        SetXSecRxDecryptDpCtl(A, xpnThreshold0_f, &ds, val_ary_rx);

        val_ary_tx[0] = p_glb_cfg->tx_pn_thrd&0xFFFFFFFF;
        SetXSecTxEncryptDpCtl(V, pnThreshold0_f, &ds1, val_ary_tx[0]);
        val_ary_rx[0] = p_glb_cfg->rx_pn_thrd&0xFFFFFFFF;
        SetXSecRxDecryptDpCtl(V, pnThreshold0_f, &ds, val_ary_rx[0]);

        /* 4.set  algorithm_type */
        SetXSecRxDecryptDpCtl(V, dpDecryptType_f, &ds, p_glb_cfg->algorithm_type);
        SetXSecTxEncryptDpCtl(V, dpEncryptType_f, &ds1, p_glb_cfg->algorithm_type);

        cmd = DRV_IOW(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        cmd = DRV_IOW(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds1));
        if (p_glb_cfg->tx_pn_overflow_action)
        {
            return CTC_E_NOT_SUPPORT;
        }

        cmd = DRV_IOR(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        /*5. Encode shim header select*/
        /*Note:max_sec_type: vxlan-0; gre-1; udp-2; ip-3
          When ctc_sh_mode enable, the cid from rsv field is different between vxlan and gre packet*/
        for (index = 0; index < max_sec_type; index++)
        {
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect4_f + index, &ds, p_glb_cfg->ctc_sh_mode? ((index&0x1)?8:4) : 9);
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect5_f + index, &ds, p_glb_cfg->ctc_sh_mode? ((index&0x1)?7:5) : 9);
            SetXSecTxEncryptDpCtl(V, array_0_strangeFieldSelect_f + index, &ds, p_glb_cfg->ctc_sh_mode? 6 : 0);
            SetXSecTxEncryptDpCtl(V, array_0_strangeFieldshift_f + index, &ds, p_glb_cfg->ctc_sh_mode? 3 : 0);
            if (p_glb_cfg->ctc_sh_mode)
            {
                shim_mask[1] = 0xFF;
            }
            SetXSecTxEncryptDpCtl(A, array_0_ctcSecShimMask_f + index, &ds, shim_mask);
        }
        cmd = DRV_IOW(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        /* 6. config global key type */
        if (CTC_DOT1AE_PKT_NONE != p_glb_cfg->key_type.packet_type)
        {
            if (CTC_INGRESS == p_glb_cfg->key_type.dir)
            {
                /* decryption key type config */
                _sys_at_dot1ae_get_keytype_profile(lchip, p_glb_cfg->key_type.packet_type, CTC_INGRESS, &key_type_field, NULL);
                cmd = DRV_IOW(XSecRxLookupDpCtl_t, key_type_field);
                key_type = p_glb_cfg->key_type.key_type;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &key_type));
            }
            else
            {
                /* encryption key type config */
                key_type = (CTC_DOT1AE_KEY_MACSEC == p_glb_cfg->key_type.key_type) ? SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC : p_glb_cfg->key_type.key_type;
                cmd = DRV_IOR(XSecTxLookupDpCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds1));
                if (CTC_DOT1AE_PKT_MACSEC == p_glb_cfg->key_type.packet_type)
                {
                    SetXSecTxLookupDpCtl(V, keyType0_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType1_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType2_f, &ds1, key_type);
                }
                else if (CTC_DOT1AE_PKT_IPV4 == p_glb_cfg->key_type.packet_type)
                {
                    SetXSecTxLookupDpCtl(V, keyType3_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType5_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType7_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType11_f, &ds1, key_type);
                }
                else if (CTC_DOT1AE_PKT_IPV6 == p_glb_cfg->key_type.packet_type)
                {
                    SetXSecTxLookupDpCtl(V, keyType4_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType6_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType8_f, &ds1, key_type);
                    SetXSecTxLookupDpCtl(V, keyType12_f, &ds1, key_type);
                }
                else if (CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH == p_glb_cfg->key_type.packet_type ||\
                        CTC_DOT1AE_PKT_CLOUDSEC_IPV4_CTCSH == p_glb_cfg->key_type.packet_type ||\
                        CTC_DOT1AE_PKT_CTCSEC_IPV6_CTCSH == p_glb_cfg->key_type.packet_type ||\
                        CTC_DOT1AE_PKT_CLOUDSEC_IPV6_CTCSH == p_glb_cfg->key_type.packet_type)
                {
                    SetXSecTxLookupDpCtl(V, keyType10_f, &ds1, key_type);
                }
                else
                {
                    SetXSecTxLookupDpCtl(V, keyType9_f, &ds1, key_type);
                }
                cmd = DRV_IOW(XSecTxLookupDpCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds1));
            }
        }
    }

    return CTC_E_NONE;
}

int32
sys_at_dot1ae_chk_pp_id(uint8 lchip, uint32 chan_id)
{
    uint8 lchip_start = 0, lchip_end = 0, all_chip = 1;
    uint8 cur_pp_id = lchip % SYS_PP_NUM(lchip);
    sys_dot1ae_chan_t* p_sys_chan = NULL;

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_chip)
    {
        p_sys_chan = _sys_usw_dot1ae_chan_lookup(lchip, chan_id);
        if (p_sys_chan && p_sys_chan->binded && p_sys_chan->pp_id != cur_pp_id)
        {
            SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"Sec-chan %u already binded entry or port from  pp %u!\n",chan_id, p_sys_chan->pp_id);
            return CTC_E_INVALID_CONFIG;
        }
    }

    return CTC_E_NONE;
}

int32
sys_at_dot1ae_set_hash_field_sel(uint8 lchip,    void* hash_sel)
{
    uint32 cmd = 0;
    uint32 tbl_id = 0;
    uint32 key_type_field_id = 0;
    uint32 profile_field_id = 0;
    uint32 maskbmp_field_id = 0;
    uint32 key_type = 0;
    uint32 old_profile_id = 0;
    uint32 new_profile_id = 0;
    uint16 step = 0;
    uint32 sub_chan_id = 0;
    uint32 dp_id = 0;
    sys_dot1ae_maskbmp_t new_maskbmp;
    sys_dot1ae_maskbmp_t old_maskbmp;
    sys_dot1ae_maskbmp_t* p_out_maskbmp =  NULL;
    ctc_dot1ae_hash_sel_t* p_hash_sel = (ctc_dot1ae_hash_sel_t*)hash_sel;
    ctc_spool_t* spool = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    CTC_MAX_VALUE_CHECK(p_hash_sel->field_cnt, CTC_DOT1AE_FIELD_KEY_NUM);

    sal_memset(&new_maskbmp, 0, sizeof(sys_dot1ae_maskbmp_t));
    sal_memset(&old_maskbmp, 0, sizeof(sys_dot1ae_maskbmp_t));

    dmps_port_info.gport = p_hash_sel->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
    SYS_DOT1AE_GET_DP_ID(lchip, p_hash_sel->gport, dp_id);
    spool = (CTC_INGRESS == p_hash_sel->dir) ? (dp_id ? usw_dot1ae_master[lchip]->dp1_rx_spool : usw_dot1ae_master[lchip]->dp0_rx_spool):\
                                               (dp_id ? usw_dot1ae_master[lchip]->dp1_tx_spool : usw_dot1ae_master[lchip]->dp0_tx_spool);
#ifdef EMULATION_ENV
/*emulation only one DP*/
 if(dp_id)
 {
     return CTC_E_NONE;
 }
#endif
    /* read key type form global cfg */
    _sys_at_dot1ae_get_keytype_profile(lchip, p_hash_sel->packet_type, p_hash_sel->dir, &key_type_field_id, &profile_field_id);
    tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupDpCtl_t : XSecTxLookupDpCtl_t;
    cmd = DRV_IOR(tbl_id, key_type_field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &key_type));
    if (SYS_DOT1AE_HASH_KEY_TYPE_NONE == key_type)
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"Please config key-type for this packet type \n");
        return CTC_E_NOT_READY;
    }

    /* get old profileID */
    tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupChanCtl_t : XSecTxLookupChanCtl_t;
    cmd = DRV_IOR(tbl_id, profile_field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &old_profile_id));
    /* get old maskbitmap according to old profileID */
    step = (CTC_INGRESS == p_hash_sel->dir) ? (XSecRxLookupDpCtl_array_1_maskBitmap_f - XSecRxLookupDpCtl_array_0_maskBitmap_f):\
                                              (XSecTxLookupDpCtl_array_1_maskBitmap_f - XSecTxLookupDpCtl_array_0_maskBitmap_f);
    maskbmp_field_id = (CTC_INGRESS == p_hash_sel->dir) ? (XSecRxLookupDpCtl_array_0_maskBitmap_f + step * old_profile_id):\
                                                          (XSecTxLookupDpCtl_array_0_maskBitmap_f + step * old_profile_id);
    tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupDpCtl_t : XSecTxLookupDpCtl_t;
    cmd = DRV_IOR(tbl_id, maskbmp_field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &old_maskbmp.mask_bitmap));

    if (0 != p_hash_sel->field_cnt)
    {
        /* check hash key capability according to key type and key field list */
        CTC_ERROR_RETURN(_sys_at_dot1ae_chk_key_type(lchip, key_type, p_hash_sel->field_key_list, p_hash_sel->field_cnt));

        /* build new maskbitmap according to key_type and key-field-list */
        new_maskbmp.mask_bitmap = _sys_at_dot1ae_build_maskbmp(lchip, key_type, p_hash_sel->dir, p_hash_sel->field_key_list, p_hash_sel->field_cnt);

        if (SYS_AT_DOT1AE_MASKBMP_EMPTY == old_profile_id)
        {/* if first use, add new maskbmp to spool */
            CTC_ERROR_RETURN(ctc_spool_add(spool, &new_maskbmp, NULL, &p_out_maskbmp));
        }
        else
        {
            CTC_ERROR_RETURN(ctc_spool_add(spool, &new_maskbmp, &old_maskbmp, &p_out_maskbmp));
        }
        if (NULL == p_out_maskbmp)
        {
            return CTC_E_NO_MEMORY;
        }
        /* set new profile_id */
        new_profile_id = p_out_maskbmp->index.index;
        CTC_ERROR_RETURN(_sys_at_dot1ae_set_profileid(lchip, p_hash_sel->dir, sub_chan_id, dp_id, profile_field_id, new_profile_id));

        /* set new maskbitmap */
        maskbmp_field_id = (CTC_INGRESS == p_hash_sel->dir) ? (XSecRxLookupDpCtl_array_0_maskBitmap_f + step * new_profile_id):\
                                                              (XSecTxLookupDpCtl_array_0_maskBitmap_f + step * new_profile_id);
        tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupDpCtl_t : XSecTxLookupDpCtl_t;
        cmd = DRV_IOW(tbl_id, maskbmp_field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &new_maskbmp.mask_bitmap));
    }
    else
    {
        /* remove maskbitmap in spool */
        CTC_ERROR_RETURN(ctc_spool_remove(spool, &old_maskbmp, NULL));

        /* clear old profileID */
        old_profile_id = 0;
        CTC_ERROR_RETURN(_sys_at_dot1ae_set_profileid(lchip, p_hash_sel->dir, sub_chan_id, dp_id, profile_field_id, old_profile_id));
    }

    return CTC_E_NONE;
}

int32
sys_at_dot1ae_get_hash_field_sel(uint8 lchip, void* hash_sel)
{
    uint32 cmd = 0;
    uint32 tbl_id = 0;
    uint32 key_type_field_id = 0;
    uint32 profile_field_id = 0;
    uint32 maskbmp_field_id = 0;
    uint32 key_type = 0;
    uint32 profile_id = 0;
    uint16 step = 0;
    uint32 sub_chan_id = 0;
    uint32 dp_id = 0;
    sys_dot1ae_maskbmp_t maskbmp;
    ctc_dot1ae_hash_sel_t* p_hash_sel = (ctc_dot1ae_hash_sel_t*)hash_sel;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    dmps_port_info.gport = p_hash_sel->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan_id));
    SYS_DOT1AE_GET_DP_ID(lchip, p_hash_sel->gport, dp_id);

    /* read key type from global cfg */
    _sys_at_dot1ae_get_keytype_profile(lchip, p_hash_sel->packet_type, p_hash_sel->dir, &key_type_field_id, &profile_field_id);
    tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupDpCtl_t : XSecTxLookupDpCtl_t;
    cmd = DRV_IOR(tbl_id, key_type_field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &key_type));
    if (SYS_DOT1AE_HASH_KEY_TYPE_NONE == key_type)
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"Key-type is none for this packet type \n");
        return CTC_E_NOT_READY;
    }

    /* get profileID */
    tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupChanCtl_t : XSecTxLookupChanCtl_t;
    cmd = DRV_IOR(tbl_id, profile_field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sub_chan_id, DRV_CMD_DP_EN(cmd, dp_id), &profile_id));
    /* get maskbitmap according to profileID */
    step = (CTC_INGRESS == p_hash_sel->dir) ? (XSecRxLookupDpCtl_array_1_maskBitmap_f - XSecRxLookupDpCtl_array_0_maskBitmap_f):\
                                              (XSecTxLookupDpCtl_array_1_maskBitmap_f - XSecTxLookupDpCtl_array_0_maskBitmap_f);
    maskbmp_field_id = (CTC_INGRESS == p_hash_sel->dir) ? (XSecRxLookupDpCtl_array_0_maskBitmap_f + step * profile_id):\
                                                          (XSecTxLookupDpCtl_array_0_maskBitmap_f + step * profile_id);
    tbl_id = (CTC_INGRESS == p_hash_sel->dir) ? XSecRxLookupDpCtl_t : XSecTxLookupDpCtl_t;
    cmd = DRV_IOR(tbl_id, maskbmp_field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &maskbmp.mask_bitmap));

    CTC_ERROR_RETURN(_sys_at_dot1ae_parser_maskbmp(lchip, key_type, p_hash_sel->field_key_list, p_hash_sel, maskbmp.mask_bitmap));

    return CTC_E_NONE;
}



int32
sys_at_dot1ae_add_entry(uint8 lchip, void* ctc_entry)
{
    int32 ret = 0;
    int32 sa_idx = 0;
    sys_dot1ae_chan_t* p_sys_sec_chan = NULL;
    sys_dot1ae_entry_t* p_sys_dot1ae_entry = NULL;
    sys_com_dot1ae_bind_sc_t bind_sc;
    uint32  offset = 0;
    uint32 update_flag = 0;
    uint32 sys_key_type = 0;
    sys_usw_opf_t opf;
    ds_t hash_key;
    ctc_dot1ae_entry_t* p_ctc_entry = (ctc_dot1ae_entry_t*)ctc_entry;
    uint8 an = 0;

    SYS_DOT1AE_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_ctc_entry->p_field_key);
    CTC_MAX_VALUE_CHECK(p_ctc_entry->key_type, CTC_DOT1AE_KEY_MAX - 1);
    if (CTC_DOT1AE_KEY_L2 == p_ctc_entry->key_type && CTC_INGRESS != p_ctc_entry->dir)
    {
        return CTC_E_INVALID_CONFIG;
    }
    sal_memset(&bind_sc, 0, sizeof(bind_sc));
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    sal_memset(hash_key, 0, sizeof(ds_t));

    sys_key_type = (CTC_DOT1AE_KEY_MACSEC == p_ctc_entry->key_type && CTC_EGRESS == p_ctc_entry->dir) ? SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC : p_ctc_entry->key_type;
    CTC_ERROR_RETURN(_sys_at_dot1ae_chk_key_type(lchip, sys_key_type, p_ctc_entry->p_field_key, p_ctc_entry->field_cnt));

    /*step1. Creat entry and add to db*/
    p_sys_dot1ae_entry = sys_usw_dot1ae_lkup_entry(lchip, p_ctc_entry->entry_id);
    if (p_sys_dot1ae_entry)
    {
        return CTC_E_EXIST;
    }
    p_sys_sec_chan = _sys_usw_dot1ae_chan_lookup(lchip, p_ctc_entry->chan_id);
    if (p_sys_sec_chan == NULL)
    {
        return CTC_E_NOT_EXIST;
    }
    if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
    {
        return CTC_E_INVALID_PARAM;
    }
    if ((p_ctc_entry->dir == CTC_INGRESS && p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX) ||
        (p_ctc_entry->dir == CTC_EGRESS && p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX))
    {
        return CTC_E_INVALID_PARAM;
    }

    p_sys_dot1ae_entry = mem_malloc(MEM_DOT1AE_MODULE, sizeof(sys_dot1ae_entry_t));
    if (p_sys_dot1ae_entry == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_sys_dot1ae_entry, 0, sizeof(sys_dot1ae_entry_t));
    p_sys_dot1ae_entry->key_type = p_ctc_entry->key_type;
    p_sys_dot1ae_entry->chan_id = p_ctc_entry->chan_id;
    p_sys_dot1ae_entry->entry_id = p_ctc_entry->entry_id;
    p_sys_dot1ae_entry->key_type = p_ctc_entry->key_type;
    p_sys_dot1ae_entry->dir = p_ctc_entry->dir;
    ret = sys_at_dot1ae_build_key(lchip, p_sys_dot1ae_entry, p_ctc_entry, hash_key);
    if (p_sys_dot1ae_entry->dp_bmp && (!SYS_GPORT_IS_NETWORK_PORT(p_sys_dot1ae_entry->gport) || SYS_USW_DOT1AE_GPORT_IS_REMOTE(lchip,p_sys_dot1ae_entry->gport)))
    {
        ret =  CTC_E_INVALID_CONFIG;
        goto step1;
    }

    if (p_sys_sec_chan->p2mp && !p_sys_dot1ae_entry->dp_bmp)
    {
        ret = CTC_E_INVALID_CONFIG;
        goto step1;
    }
    if (p_sys_dot1ae_entry->dp_bmp == 0)
    {
        p_sys_dot1ae_entry->dp_bmp = 0x3;/*for global cloudsec*/
    }

    if (p_sys_sec_chan->p2mp && (p_sys_sec_chan->binded && (p_sys_sec_chan->gport != p_sys_dot1ae_entry->gport)))
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "p2mp can not bind different gports to one sec-chan!\n");
        ret = CTC_E_INVALID_CONFIG;
        goto step1;
    }

    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
    if ((p_sys_sec_chan->ref_cnt[dp_idx] != 0 && p_sys_sec_chan->is_use_plain && CTC_DOT1AE_KEY_L2 != p_ctc_entry->key_type) || \
        (p_sys_sec_chan->ref_cnt[dp_idx] != 0 && !p_sys_sec_chan->is_use_plain && CTC_DOT1AE_KEY_L2 == p_ctc_entry->key_type))
    {
        SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Plain text entry and decryption entry can not used one sec-chan!\n");
        ret =  CTC_E_INVALID_CONFIG;
        goto step1;
    }
    SYS_DOT1AE_FOREACH_DP_END


    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_dot1ae_entry->dp_bmp)
    if ((!p_sys_sec_chan->ref_cnt[dp_idx]) && CTC_DOT1AE_KEY_L2 != p_ctc_entry->key_type)
    {
        opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
        opf.pool_index = ((p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
        ret = sys_usw_opf_alloc_offset(lchip, &opf, 1, &offset);
        if (ret < 0)
        {
            goto step1;
        }
        p_sys_sec_chan->sc_index[dp_idx] = offset;
    }

    p_sys_dot1ae_entry->sc_index[dp_idx] = p_sys_sec_chan->sc_index[dp_idx];
    SYS_DOT1AE_FOREACH_DP_END

    if (FALSE == ctc_hash_insert(usw_dot1ae_master[lchip]->entry_hash, p_sys_dot1ae_entry))
    {
        ret =  CTC_E_NO_MEMORY;
        goto step2;
    }

    /*step3. Set dot1ae field to asic */
    p_sys_sec_chan->pp_id = lchip % SYS_PP_NUM(lchip);
    p_sys_sec_chan->binding_type = (CTC_DOT1AE_KEY_MACSEC == p_ctc_entry->key_type)? SYS_DOT1AE_BIND_TYPE_PORT : SYS_DOT1AE_BIND_TYPE_ENTRY;
    p_sys_sec_chan->is_use_plain = CTC_DOT1AE_KEY_L2 == p_ctc_entry->key_type;



    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_dot1ae_entry->dp_bmp)
    if (!p_sys_sec_chan->ref_cnt[dp_idx] && !p_sys_sec_chan->is_use_plain)
    {
        p_sys_sec_chan->dp_id =dp_idx;
        CTC_ERROR_GOTO(sys_at_dot1ae_reset_sec_chan_cfg(lchip, (void*) p_sys_sec_chan), ret, step3);
        CTC_ERROR_GOTO(sys_at_dot1ae_add_sc_to_asic(lchip, (void*) p_sys_sec_chan), ret, step3);
        CTC_SET_FLAG(update_flag, (CTC_DOT1AE_SA_FLAG_NEXT_PN | CTC_DOT1AE_SA_FLAG_KEY | CTC_DOT1AE_SA_FLAG_ENCRYPTION |
        CTC_DOT1AE_SA_FLAG_ICV_ERROR_ACTION | CTC_DOT1AE_SA_FLAG_VALIDATEFRAMES));
        for (an = 0; an < MCHIP_CAP(SYS_CAP_DOT1AE_AN_NUM); an++)
        {
            if (CTC_IS_BIT_SET(p_sys_sec_chan->an_valid, an))
            {
                CTC_ERROR_GOTO(sa_idx = _sys_tmm_dot1ae_lkup_sec_sa_idx(lchip, an, p_sys_sec_chan), ret, step3);
                CTC_ERROR_GOTO(sys_at_dot1ae_add_sa_to_asic(lchip, p_sys_sec_chan, sa_idx, update_flag), ret, step3);
            }
        }
    }
    /*step4. per port Set XSecRxLookupChanCtl/XSecTxLookupChanCtl and XSecTxChanCtl */
    if (p_sys_sec_chan->p2mp)
    {
        CTC_ERROR_GOTO(sys_at_dot1ae_set_chan_ctl(lchip, p_sys_sec_chan), ret, step3);
    }
    /*step5. Set key/ad field to asic */
    ret = _sys_at_dot1ae_set_key_to_asic(lchip, p_sys_dot1ae_entry, hash_key, 0,dp_idx);
    if (ret < 0)
    {
        goto step3;
    }
    p_sys_sec_chan->ref_cnt[dp_idx]++;
    SYS_DOT1AE_FOREACH_DP_END

    p_sys_sec_chan->binded = 1;
    p_sys_sec_chan->gport = p_sys_dot1ae_entry->gport;
    p_sys_sec_chan->dp_bmp |= p_sys_dot1ae_entry->dp_bmp;

    goto RETURN;

    step3:
    ctc_hash_remove(usw_dot1ae_master[lchip]->entry_hash, p_sys_dot1ae_entry);
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_dot1ae_entry->dp_bmp)
    if (p_sys_sec_chan->ref_cnt[dp_idx] == 0 && CTC_DOT1AE_KEY_L2 == p_ctc_entry->key_type)
    {
        p_sys_sec_chan->is_use_plain = 0;
    }
    SYS_DOT1AE_FOREACH_DP_END

    step2:
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_dot1ae_entry->dp_bmp)
    if (p_sys_sec_chan->ref_cnt[dp_idx] == 0)
    {
        opf.pool_index = ((p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
        sys_usw_opf_free_offset(lchip, &opf, 1, p_sys_sec_chan->sc_index[dp_idx]);
    }
    SYS_DOT1AE_FOREACH_DP_END

    step1:
    if (p_sys_dot1ae_entry)
    {
        mem_free(p_sys_dot1ae_entry);
    }
    RETURN:
    return ret;
}

int32
sys_at_dot1ae_show_entry(uint8 lchip,void* param)
{
    uint16 entry_number =1;
    sys_traverse_t user_data;
    sys_dot1ae_show_entry_info_t* entry_param = (sys_dot1ae_show_entry_info_t*)param;
    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.data = param;
    user_data.data1 = (void*)&entry_number;
    user_data.value1 = lchip;

    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "------------------------------Dot1AE Entry Info-----------------------------------\n");
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-12s %-12s %-14s %-14s %-14s \n","No.","Entry_id","Key_index_dp0","Key_index_dp1","Key_type");
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------------------------\n");
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->entry_hash, (hash_traversal_fn)_sys_at_dot1ae_show_entry_traverse, (void *)&user_data));

    if (entry_param->detail)
    {
        user_data.value1 = entry_param->detail;
        entry_number=1;
        CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->entry_hash, (hash_traversal_fn)_sys_at_dot1ae_show_entry_traverse, (void *)&user_data));

    }
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-----------------------------------------------------------------------------------\n");
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Total entry number: %u\n",entry_number-1);
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
   return CTC_E_NONE;
}

int32
sys_at_dot1ae_remove_entry(uint8 lchip, uint32 entry_id)
{
    int32 ret = 0;
    sys_usw_opf_t opf;
    sys_dot1ae_entry_t* p_sys_dot1ae_entry =NULL;
    sys_dot1ae_chan_t* p_sys_sec_chan = NULL;
    sys_traverse_t user_data;

    SYS_DOT1AE_INIT_CHECK(lchip);
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    sal_memset(&user_data, 0, sizeof(sys_traverse_t));
    p_sys_dot1ae_entry = sys_usw_dot1ae_lkup_entry(lchip, entry_id);
    if (!p_sys_dot1ae_entry)
    {
        return CTC_E_NOT_EXIST;
    }
    p_sys_sec_chan = _sys_usw_dot1ae_chan_lookup(lchip, p_sys_dot1ae_entry->chan_id);
    if (p_sys_sec_chan == NULL)
    {
        return CTC_E_NOT_EXIST;
    }
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_dot1ae_entry->dp_bmp)
    ret = _sys_at_dot1ae_set_key_to_asic(lchip, p_sys_dot1ae_entry, NULL,1,dp_idx);
    if (p_sys_sec_chan->ref_cnt[dp_idx])
    {
        p_sys_sec_chan->ref_cnt[dp_idx]--;
    }

    if (p_sys_sec_chan->ref_cnt[dp_idx]==0 && CTC_DOT1AE_KEY_L2 != p_sys_dot1ae_entry->key_type)
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
        opf.pool_index = ((p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
        sys_usw_opf_free_offset(lchip, &opf, 1, p_sys_sec_chan->sc_index[dp_idx]);

        CTC_BIT_UNSET(p_sys_sec_chan->dp_bmp, dp_idx);
    }
    else if (p_sys_sec_chan->ref_cnt[dp_idx] == 0 && CTC_DOT1AE_KEY_L2 == p_sys_dot1ae_entry->key_type)
    {
        p_sys_sec_chan->is_use_plain = 0;
        CTC_BIT_UNSET(p_sys_sec_chan->dp_bmp, dp_idx);
    }
    SYS_DOT1AE_FOREACH_DP_END
    if ((p_sys_sec_chan->ref_cnt[0] + p_sys_sec_chan->ref_cnt[1])==0)
    {
        p_sys_sec_chan->binded = 0;
        p_sys_sec_chan->binding_type = 0;
        p_sys_sec_chan->is_use_plain = (CTC_DOT1AE_KEY_L2 == p_sys_dot1ae_entry->key_type)? 0 : p_sys_sec_chan->is_use_plain;
    }
    ctc_hash_remove(usw_dot1ae_master[lchip]->entry_hash, p_sys_dot1ae_entry);
    mem_free(p_sys_dot1ae_entry);

    return ret;
}
STATIC int32
_sys_at_dot1ae_isr_get_defect_name(uint8 lchip, ctc_dot1ae_event_entry_t* intrp_info)
{
    uint8 index = 0;

    for (index = 0; index < 3; index++)
    {
        if (CTC_IS_BIT_SET(intrp_info->event_bmp, index))
        {
            switch (1<<index)
            {
                case CTC_DOT1AE_EVENT_PN_OVER_FLOW:
                    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Event name: %s\r\n", " PN exhaust.");
                    break;
                case CTC_DOT1AE_EVENT_AN_SWITCH:
                    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Event name: %s\r\n", " AN switch.");
                    break;
                default:
                    break;
            }
        }
    }
    return CTC_E_NONE;
}

int32
sys_at_isr_dot1ae_process_isr(uint8 gchip, void* p_data)
{
    uint16 chan_num = 0;
    ctc_dot1ae_event_t* p_event = NULL;
    uint8 lchip = 0;

    CTC_PTR_VALID_CHECK(p_data);
    CTC_ERROR_RETURN(sys_usw_get_local_chip_id(gchip, &lchip));
    SYS_DOT1AE_INIT_CHECK(lchip);
    SYS_LCHIP_CHECK_ACTIVE(lchip);
    p_event = (ctc_dot1ae_event_t*)p_data;
    for (chan_num = 0; chan_num < p_event->valid_num; chan_num++)
    {
         SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nDot1AE Event,  Chan ID: %u,  Sa inuse:%d Dir: %s\n",
            p_event->event_entry[chan_num].chan_id, p_event->event_entry[chan_num].sa_inuse,
            p_event->event_entry[chan_num].dir == CTC_DOT1AE_SC_DIR_TX? "Tx" : "Rx");
        CTC_ERROR_DUMP(_sys_at_dot1ae_isr_get_defect_name(lchip, &p_event->event_entry[chan_num]));
    }
    return CTC_E_NONE;
}

STATIC int32
sys_at_dot1ae_isr_defect(uint8 lchip, uint32 intr, void* p_data)
{
    uint8 gchip = 0;
    ctc_dot1ae_event_t event;
    CTC_INTERRUPT_EVENT_FUNC dot1ae_intrp_cb = NULL;
    uint32 do_intr_table_cnt = 0;
    uint32 do_intr_table_num = 0;
    int32 ret = CTC_E_NONE;
    ds_t ds_intrp;
    sys_dot1ae_chan_t  sys_sec_chan;
    sys_dot1ae_chan_t*  p_sys_sec_chan=NULL;
    uint32 cmd = 0;
    uint32 encoding_sa_tx = 0;
    uint32 dp_id = 0;
    uint8 pp_id =0;
    uint8 is_tx_event =0;
    uint8 idx =0;
    uint32 macsecpn[2]={0};
    uint32* per_dp_intr = (uint32*)p_data;
	uint8 index=0;
    sys_traverse_t user_data;
    SYS_DOT1AE_INIT_CHECK(lchip);
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    
    sal_memset(&sys_sec_chan, 0 , sizeof(sys_dot1ae_chan_t));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_DOT1AE, &dot1ae_intrp_cb));
    if (!dot1ae_intrp_cb)
    {
        return CTC_E_NOT_INIT;
    }
    sal_memset(&event, 0, sizeof(ctc_dot1ae_event_t));
    SYS_DOT1AE_LOCK(lchip);

    for (index = 0; index < SYS_DOT1AE_INTR_EVENT_NUM_PER_CORE; index++)
    {
        if (!CTC_BMP_ISSET(per_dp_intr, index))
        {
            continue;
        }
        pp_id = (index % (SYS_DOT1AE_INTR_EVENT_NUM_PER_CORE / 2)) / 2;
        dp_id = index % 2;
        is_tx_event = index >= (SYS_DOT1AE_INTR_EVENT_NUM_PER_CORE / 2);

        do_intr_table_num = MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM);
        for (do_intr_table_cnt = 0; do_intr_table_cnt < do_intr_table_num; do_intr_table_cnt++)
        {
            cmd = DRV_IOR(is_tx_event ? XSecTxScIntrp_t : XSecRxScIntrp_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip + pp_id, do_intr_table_cnt, DRV_CMD_DP_EN(cmd, dp_id), &ds_intrp), ret, End);

            sys_sec_chan.sc_index[dp_id] = do_intr_table_cnt;
            sys_sec_chan.dir = is_tx_event ? CTC_DOT1AE_SC_DIR_TX : CTC_DOT1AE_SC_DIR_RX;
            sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
            user_data.data = (void *)&sys_sec_chan;
            user_data.value1 = lchip;
            user_data.value2 = dp_id;
            ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_at_dot1ae_get_chan_by_idx_traverse, (void *)&user_data);
            if (0 == user_data.value3)
            {
                continue;
            }
            event.event_entry[event.valid_num].chan_id = sys_sec_chan.chan_id;
            if (CTC_BMP_ISSET(ds_intrp, 0))
            {
                CTC_SET_FLAG(event.event_entry[event.valid_num].event_bmp, CTC_DOT1AE_EVENT_PN_OVER_FLOW);
            }

            if (is_tx_event && CTC_BMP_ISSET(ds_intrp, 1))
            {
                for (idx = 0; idx < MCHIP_CAP(SYS_CAP_DOT1AE_AN_NUM); idx++)
                {

                    if (CTC_IS_BIT_SET(sys_sec_chan.an_en, idx))
                    {
                        break;
                    }
                }

                CTC_SET_FLAG(event.event_entry[event.valid_num].event_bmp, CTC_DOT1AE_EVENT_AN_SWITCH);
                    encoding_sa_tx = _sys_tmm_dot1ae_lkup_sec_sa_idx(lchip, idx, &sys_sec_chan);

                macsecpn[0] = 1;
                cmd = DRV_IOW(DsXSecEncryptSaStatus_t, DsXSecEncryptSaStatus_xpn_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip + pp_id, (do_intr_table_cnt << 1) + (encoding_sa_tx % 2), DRV_CMD_DP_EN(cmd, dp_id), macsecpn), ret, End);
                p_sys_sec_chan = _sys_usw_dot1ae_chan_lookup(lchip, sys_sec_chan.chan_id);
                if (NULL == p_sys_sec_chan)
                {
                    ret = CTC_E_NOT_EXIST;
                    goto End;
                }
                p_sys_sec_chan->an_en = p_sys_sec_chan->an_valid & (~p_sys_sec_chan->an_en);
            }

            if (CTC_BMP_ISSET(ds_intrp, 0) || (is_tx_event && CTC_BMP_ISSET(ds_intrp, 1)))
            {
                event.event_entry[event.valid_num].sa_inuse = sys_sec_chan.an_en;
                event.event_entry[event.valid_num].dir = is_tx_event ? CTC_DOT1AE_SC_DIR_TX : CTC_DOT1AE_SC_DIR_RX;
                event.valid_num++;
            }
            if (event.valid_num >= CTC_DOT1AE_EVENT_MAX_NUM)
            {
                SYS_DOT1AE_UNLOCK(lchip);
                CTC_ERROR_RETURN(dot1ae_intrp_cb(gchip, &event));
                SYS_DOT1AE_LOCK(lchip);
                event.valid_num = 0;
            }
            if (1 == SDK_WORK_PLATFORM)
            {
                sal_memset(&ds_intrp, 0, sizeof(ds_t));
                cmd = DRV_IOW(is_tx_event ? XSecTxScIntrp_t : XSecRxScIntrp_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip + pp_id, do_intr_table_cnt, DRV_CMD_DP_EN(cmd, dp_id), &ds_intrp), ret, End);
            }
        }
    }

	if (event.valid_num > 0)
	  {
		  SYS_DOT1AE_UNLOCK(lchip);
		  CTC_ERROR_RETURN(dot1ae_intrp_cb(gchip, &event));
		  SYS_DOT1AE_LOCK(lchip);
	  }
End:
    SYS_DOT1AE_UNLOCK(lchip);
    return ret;
}
int32 sys_at_dot1ae_set_hash_type(uint8 lchip, sys_com_dot1ae_hash_type_t* p_hash_type)
{
    uint32 port = 0;
    uint32 cmd=0;
    uint32 tbl_id=0;
    uint16 field_id=0;
    uint32 dp_id=0;
    uint8 sec_type =0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds,ds1;
    CTC_MAX_VALUE_CHECK(p_hash_type->type, 2);
    dmps_port_info.gport = p_hash_type->gport;
    tbl_id = p_hash_type->dir? XSecTxLookupChanCtl_t : XSecRxLookupChanCtl_t;
    field_id = p_hash_type->dir? XSecTxLookupChanCtl_cryptoType_f : XSecRxLookupChanCtl_cryptoType_f;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &port));
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    SYS_DOT1AE_GET_DP_ID(lchip, p_hash_type->gport,dp_id);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port, DRV_CMD_DP_EN(cmd,dp_id), &ds));

    if (p_hash_type->dir == CTC_EGRESS)
    {
        cmd = DRV_IOR(XSecTxChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, port, DRV_CMD_DP_EN(cmd, dp_id), &ds1));
        sec_type = GetXSecTxChanCtl(V, ctcSecType_f, &ds1);
    }

    if (!p_hash_type->is_set)
    {
        p_hash_type->type= DRV_GET_FIELD_V(lchip, tbl_id, field_id, &ds) + sec_type;
        return CTC_E_NONE;
    }

    DRV_SET_FIELD_V(lchip, tbl_id, field_id, &ds, !!p_hash_type->type);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port, DRV_CMD_DP_EN(cmd, dp_id), &ds));
    if (p_hash_type->dir == CTC_EGRESS)
    {
        cmd = DRV_IOW(XSecTxChanCtl_t, DRV_ENTRY_FLAG);
        SetXSecTxChanCtl(V, ctcSecType_f, &ds1, (p_hash_type->type >> 1));
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, port, DRV_CMD_DP_EN(cmd, dp_id), &ds1));
    }
    return CTC_E_NONE;

}

int32
sys_at_dot1ae_register_init(uint8 lchip)
{
    ds_t ds;
    uint32 dp_id=0;
    uint8 cur_pp_id = 0;
    uint32 cmd=0;
    uint32 val_ary[2]={0};
    uint8 max_sec_type =4;
    uint8 index =0;
    uint32 shim_mask[2]={0xFFFF00FF,0xFFFF};
    ctc_dot1ae_hash_sel_t hash_sel;
    uint16 lport = 0;
    uint8 gchip = 0;
    uint8 sub_chan=0;
    uint32 key_field_id = 0;
    int32 ret =0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&ds, 0, sizeof(ds));
    sal_memset(&hash_sel, 0, sizeof(ctc_dot1ae_hash_sel_t));

    for (dp_id = 0; dp_id < 2; dp_id++)
    {
        /*Rx register init*/
        cmd = DRV_IOR(XSecRxParserDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecRxParserDpCtl(V, array_0_cvlanTpid_f, &ds, 0x8100);
        SetXSecRxParserDpCtl(V, array_0_svlanTpid_f, &ds, 0x8100);
        SetXSecRxParserDpCtl(V, macsecEtherType0_f, &ds, 0x88e5);
        SetXSecRxParserDpCtl(V, macsecEtherType1_f, &ds, 0x88e5);
        SetXSecRxParserDpCtl(V, ipCtcSecProtocol_f, &ds, 0xfe);
        SetXSecRxParserDpCtl(V, v6OptionChk_f, &ds, 1);/* config check not support ipv6-ext-hdr */
        SetXSecRxParserDpCtl(V, v6ExtPro0_f, &ds, 43);
        SetXSecRxParserDpCtl(V, v6ExtPro1_f, &ds, 44);
        SetXSecRxParserDpCtl(V, v6ExtPro2_f, &ds, 58);
        SetXSecRxParserDpCtl(V, v6ExtPro3_f, &ds, 59);
        SetXSecRxParserDpCtl(V, v6ExtPro4_f, &ds, 60);
        SetXSecRxParserDpCtl(V, v6ExtPro5_f, &ds, 135);
        SetXSecRxParserDpCtl(V, v6ExtPro6_f, &ds, 140);
        SetXSecRxParserDpCtl(V, v6ExtPro7_f, &ds, 143);
        SetXSecRxParserDpCtl(V, ipCtcSecShimProtocol_f, &ds, 0xfd);
        cmd = DRV_IOW(XSecRxParserDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecRxDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecRxDpCtl(V, xSecEn_f, &ds, 1);
        cmd = DRV_IOW(XSecRxDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecTxDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecTxDpCtl(V, xSecEn_f, &ds, 1);
        cmd = DRV_IOW(XSecTxDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(NetRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetNetRxCtl(V, cfgXSecDecEnable_f, ds, 1);
        cmd = DRV_IOW(NetRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        
        cmd = DRV_IOR(EpeScheduleMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetEpeScheduleMiscCtl(V, cfgXSecGlobalEn_f, ds, 1);
        cmd = DRV_IOW(EpeScheduleMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        
        SetCtcDpRxCtlClockEn(V, enClkXSecDec_f, &ds, 1);
        cmd = DRV_IOW(CtcDpRxCtlClockEn_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        
        SetCtcDpTxCtlClockEn(V, enClkXSecEnc_f, &ds, 1);
        cmd = DRV_IOW(CtcDpTxCtlClockEn_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecRxLookupDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecRxLookupDpCtl(V, keyType0_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_MACSEC);
        SetXSecRxLookupDpCtl(V, keyType1_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecRxLookupDpCtl(V, keyType2_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecRxLookupDpCtl(V, keyType3_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecRxLookupDpCtl(V, keyType5_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecRxLookupDpCtl(V, keyType7_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_SPI);
        SetXSecRxLookupDpCtl(V, keyType9_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecRxLookupDpCtl(V, keyType11_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_SPI);
        SetXSecRxLookupDpCtl(V, keyType4_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecRxLookupDpCtl(V, keyType6_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_SPI);
        SetXSecRxLookupDpCtl(V, keyType8_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecRxLookupDpCtl(V, keyType10_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_SPI);
        SetXSecRxLookupDpCtl(V, keyType12_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecRxLookupDpCtl(V, keyType13_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecRxLookupDpCtl(V, keyType14_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecRxLookupDpCtl(V, v6KeyAdrExtMode_f, &ds, 2);

        cmd = DRV_IOW(XSecRxLookupDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecRxDecryptDpCtl(V, versionChk_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, scbChk_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, slChk_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, scEsChk_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, pnChk_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, cipherModeChk_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, ctcSecUdpPortDecrypted_f, &ds, 4789);

        /*Rx SecYStats*/
        SetXSecRxDecryptDpCtl(V, macsecBadTagStatsType_f, &ds, 0);
        SetXSecRxDecryptDpCtl(V, macsecBadTagStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktNoSaStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktNoSaStatsType_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktNoSaErrorStatsType_f, &ds, 2);

        /*Rx SecYByteStats*/
        SetXSecRxDecryptDpCtl(V, macsecByteDecryptedStatsType_f, &ds, 0);
        SetXSecRxDecryptDpCtl(V, macsecByteDecryptedStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecByteValidatedStatsType_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecByteValidatedStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, invalidIcvNotCountOct_f, &ds, 1);

        /*Rx ScStats*/
        SetXSecRxDecryptDpCtl(V, macsecInPktLateStatsType_f, &ds, 0);
        SetXSecRxDecryptDpCtl(V, macsecInPktNotValidStatsType_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktInvalidStatsType_f, &ds, 2);
        SetXSecRxDecryptDpCtl(V, macsecInPktDelayedStatsType_f, &ds, 3);
        SetXSecRxDecryptDpCtl(V, macsecInPktUncheckedStatsType_f, &ds, 4);
        SetXSecRxDecryptDpCtl(V, macsecInPktOkStatsType_f, &ds, 5);
        SetXSecRxDecryptDpCtl(V, macsecInPktLateStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktNotValidStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktInvalidStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktDelayedStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktUncheckedStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, macsecInPktOkStatsValid_f, &ds, 1);

        /*Rx ChanStats*/
        SetXSecRxDecryptDpCtl(V, bypassStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, matchDiscardStatsValid_f, &ds, 1);
        SetXSecRxDecryptDpCtl(V, bypassStatsType_f, &ds, 0);
        SetXSecRxDecryptDpCtl(V, matchDiscardStatsType_f, &ds, 1);
        cmd = DRV_IOW(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        /* config rx stats and interrupt clear after reading */
        cmd = DRV_IOR(XSecDecCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecDecCtl(V, cfgCpuBlkCycle_f, &ds, 23);
        SetXSecDecCtl(V, clearOnReadChanStats_f, &ds, 1);
        SetXSecDecCtl(V, clearOnReadRxScIntrp_f, &ds, 1);
        SetXSecDecCtl(V, clearOnReadScStatsEn_f, &ds, 1);
        SetXSecDecCtl(V, clearOnReadSecYByteStatsEn_f, &ds, 1);
        SetXSecDecCtl(V, clearOnReadSecYStatsEn_f, &ds, 1);
        cmd = DRV_IOW(XSecDecCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        /*Tx register init*/
        cmd = DRV_IOR(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecTxEncryptDpCtl(V, macsecEtherType0_f, &ds, 0x88e5);
        SetXSecTxEncryptDpCtl(V, macsecEtherType1_f, &ds, 0x88e5);

        SetXSecTxEncryptDpCtl(V, padEn_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, padEnForIcvOnlyMode_f, &ds, 1);

        /*Tx SecYStats*/
        SetXSecTxEncryptDpCtl(V, macsecCtlPortDisableStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, macsecUnTagStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, lengthStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, macsecCtlPortDisableStatsType_f, &ds, 0);
        SetXSecTxEncryptDpCtl(V, macsecUnTagStatsType_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, lengthStatsType_f, &ds, 2);

        /*Tx ScStats*/
        SetXSecTxEncryptDpCtl(V, macsecSaNotInUseStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, macsecPktStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, macsecSaNotInUseStatsType_f, &ds, 0);
        SetXSecTxEncryptDpCtl(V, macsecPktProtectedStatsType_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, macsecPktEncryptedStatsType_f, &ds, 2);

        /*Tx SecYByteStats*/
        SetXSecTxEncryptDpCtl(V, macsecByteStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, macsecByteProtectedStatsType_f, &ds, 0);
        SetXSecTxEncryptDpCtl(V, macsecByteEncryptedStatsType_f, &ds, 1);

         /*Tx ChanStats*/
        SetXSecTxEncryptDpCtl(V, cfgErrorStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, bypassStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, matchDiscardStatsValid_f, &ds, 1);
        SetXSecTxEncryptDpCtl(V, cfgErrorStatsType_f, &ds, 2);
        SetXSecTxEncryptDpCtl(V, bypassStatsType_f, &ds, 0);
        SetXSecTxEncryptDpCtl(V, matchDiscardStatsType_f, &ds, 1);

        /* config short length force zero for cloudsec, follow Tsingma */
        SetXSecTxEncryptDpCtl(V, slFollowTm_f, &ds, 1);

        /*Encode shim header select*/
        for (index = 0; index < max_sec_type; index++)
        {
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect0_f + index, &ds, 9);
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect2_f + index, &ds, 9);
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect3_f + index, &ds, 9);
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect4_f + index, &ds, 9);
            SetXSecTxEncryptDpCtl(V, array_0_ctcSecShimSelect5_f + index, &ds, 9);
            SetXSecTxEncryptDpCtl(A, array_0_ctcSecShimMask_f + index, &ds, shim_mask);
        }

        cmd = DRV_IOW(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        /* config tx stats and interrupt clear after reading */
        SetXSecEncCtl(V, clearOnReadChanStats_f, &ds, 1);
        SetXSecEncCtl(V, clearOnReadScStats_f, &ds, 1);
        SetXSecEncCtl(V, clearOnReadSecYByteStats_f, &ds, 1);
        SetXSecEncCtl(V, clearOnReadSecYStats_f, &ds, 1);
        SetXSecEncCtl(V, clearOnReadTxScIntrp_f, &ds, 1);
        cmd = DRV_IOW(XSecEncCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecTxParserDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecTxParserDpCtl(V, array_0_cvlanTpid_f, &ds, 0x8100);
        SetXSecTxParserDpCtl(V, array_0_svlanTpid_f, &ds, 0x8100);
        SetXSecTxParserDpCtl(V, vxlanEn_f, &ds, 1);
        SetXSecTxParserDpCtl(V, vxlanUdpDestPort0_f, &ds, 0x12b5);
        SetXSecTxParserDpCtl(V, v6OptionChk_f, &ds, 1);/* config check not support ipv6-ext-hdr */
        SetXSecTxParserDpCtl(V, v6ExtPro0_f, &ds, 43);
        SetXSecTxParserDpCtl(V, v6ExtPro1_f, &ds, 44);
        SetXSecTxParserDpCtl(V, v6ExtPro2_f, &ds, 58);
        SetXSecTxParserDpCtl(V, v6ExtPro3_f, &ds, 59);
        SetXSecTxParserDpCtl(V, v6ExtPro4_f, &ds, 60);
        SetXSecTxParserDpCtl(V, v6ExtPro5_f, &ds, 135);
        SetXSecTxParserDpCtl(V, v6ExtPro6_f, &ds, 140);
        SetXSecTxParserDpCtl(V, v6ExtPro7_f, &ds, 143);
        SetXSecTxParserDpCtl(V, basicGreDisable_f, &ds, 1);/* config basic GRE packet disable defaultly, support NVGRE */
        cmd = DRV_IOW(XSecTxParserDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecTxLookupDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecTxLookupDpCtl(V, keyType0_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecTxLookupDpCtl(V, keyType1_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecTxLookupDpCtl(V, keyType2_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_L2_BASIC);
        SetXSecTxLookupDpCtl(V, keyType3_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecTxLookupDpCtl(V, keyType4_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecTxLookupDpCtl(V, keyType5_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecTxLookupDpCtl(V, keyType6_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecTxLookupDpCtl(V, keyType7_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecTxLookupDpCtl(V, keyType8_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecTxLookupDpCtl(V, keyType10_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_SPI);
        SetXSecTxLookupDpCtl(V, keyType11_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV4);
        SetXSecTxLookupDpCtl(V, keyType12_f, &ds, SYS_DOT1AE_HASH_KEY_TYPE_IPV6);
        SetXSecTxLookupDpCtl(V, spiValidMode_f, &ds, 1);
        SetXSecTxLookupDpCtl(V, v6KeyAdrExtMode_f, &ds, 2);
        cmd = DRV_IOW(XSecTxLookupDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecTxEncryptDpCtl(V, pnThreshold0_f, &ds, 0xc0000000);
        SetXSecTxEncryptDpCtl(V, ctcSecIpProtocol_f, &ds, 0xfe);
        SetXSecTxEncryptDpCtl(V, ctcSecShimIpProtocol_f, &ds, 0xfd);
        val_ary[0] = 0x0;
        val_ary[1] = 0xc0000000;
        SetXSecTxEncryptDpCtl(A, xpnThreshold0_f, &ds, val_ary);
        cmd = DRV_IOW(XSecTxEncryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));

        cmd = DRV_IOR(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetXSecRxDecryptDpCtl(V, pnThreshold0_f, &ds, 0xc0000000);
        val_ary[0] = 0x0;
        val_ary[1] = 0xc0000000;
        SetXSecRxDecryptDpCtl(A, xpnThreshold0_f, &ds, val_ary);
        cmd = DRV_IOW(XSecRxDecryptDpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
    }

    for (sub_chan = 0; sub_chan < MCHIP_CAP(SYS_CAP_PER_DP_PHY_PORT_NUM); sub_chan++)
    {
        if (lchip != sys_usw_vchip_get_pp_base(lchip))
        {
            break;
        }
        cmd = DRV_IOR(XSecRxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, cmd, &ds));
        SetXSecRxLookupChanCtl(V, prErrorDiscardMask_f, &ds, 0xFFFFF);
        SetXSecRxLookupChanCtl(V, prErrorBypassMask_f, &ds, 0xFFFFF);
        SetXSecRxLookupChanCtl(V, chanLabel_f, &ds, sub_chan);
        SetXSecRxLookupChanCtl(V, opType2_f, &ds, SYS_DOT1AE_OP_TYPE_BYPASS);
        cmd = DRV_IOW(XSecRxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, cmd, &ds));

        cmd = DRV_IOR(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, cmd, &ds));
        SetXSecTxLookupChanCtl(V, prErrorDiscardMask_f, &ds, 0xFFFF);
        SetXSecTxLookupChanCtl(V, prErrorBypassMask_f, &ds, 0xFFFF);
        SetXSecTxLookupChanCtl(V, chanLabel_f, &ds, sub_chan);
        cmd = DRV_IOW(XSecTxLookupChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, cmd, &ds));

        sal_memset(ds, 0, sizeof(ds_t));
        SetXSecTxChanCtl(V, ctcSecType_f, &ds, 1);
        cmd = DRV_IOW(XSecTxChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, cmd, &ds));
    }

    hash_sel.field_key_list = mem_malloc(MEM_DOT1AE_MODULE, sizeof(ctc_field_key_t)*CTC_DOT1AE_FIELD_KEY_NUM);
     if (hash_sel.field_key_list == NULL)
     {
         return CTC_E_NO_MEMORY;
     }

    /* config default mask bitmap */
    cur_pp_id = lchip % SYS_PP_NUM(lchip);
    for (lport = 0; lport < MCHIP_CAP(SYS_CAP_PORT_NUM_PER_CHIP); lport++)
    {
        uint32 port_type = 0;
        uint32 pp_id = 0;
        if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
        {
            break;
        }
        sys_usw_get_gchip_id(lchip, &gchip);
        dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
        sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, &port_type);
        if (SYS_DMPS_NETWORK_PORT != port_type)
        {
            continue;
        }
        sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id);
        if (pp_id != cur_pp_id)
        {
            continue;
        }
#ifdef EMULATION_ENV
{
extern uint8 g_drv_emu_first_pp_bmp;
    if (!CTC_IS_BIT_SET((g_drv_emu_first_pp_bmp >> 2) & 0xF, pp_id & 0x3))
    {
        continue;
    }
}
#endif


        hash_sel.gport = dmps_port_info.gport;
 
        /* 1. config default encryption maskbitmap */
        /* macsec p2mp, key: port*/
        hash_sel.dir = CTC_EGRESS;
        hash_sel.packet_type = CTC_DOT1AE_PKT_MACSEC;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* cloudsec IPv4, key: port + ip-da + ip-sa + ip-protocol*/
        hash_sel.packet_type = CTC_DOT1AE_PKT_IPV4;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_DA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_SA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_PROTOCOL;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_SRC_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_DST_PORT;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* cloudsec IPv6, key: port + ipv6-da + ipv6-sa + ip-protocol*/
        hash_sel.packet_type = CTC_DOT1AE_PKT_IPV6;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IPV6_DA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IPV6_SA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_PROTOCOL;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_SRC_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_DST_PORT;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* ctcsec with shim header, key: SPI */
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_DOT1AE_SPI;
        hash_sel.field_cnt = key_field_id;
        hash_sel.packet_type = CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* 2. config default decryption maskbitmap */
        /* macsec p2mp, key: port + SCI*/
        hash_sel.dir = CTC_INGRESS;
        hash_sel.packet_type = CTC_DOT1AE_PKT_MACSEC;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_DOT1AE_SCI;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* cloudsec IPv4, key: port + ip-da + ip-sa + ip-protocol + l4-src-port + l4-dst-port */
        hash_sel.packet_type = CTC_DOT1AE_PKT_CLOUDSEC_IPV4;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_DA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_SA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_PROTOCOL;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_SRC_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_DST_PORT;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* cloudsec IPv6, key: port + ipv6-da + ipv6-sa + ip-protocol + l4-src-port + l4-dst-port*/
        hash_sel.packet_type = CTC_DOT1AE_PKT_CLOUDSEC_IPV6;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IPV6_DA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IPV6_SA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_PROTOCOL;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_SRC_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_L4_DST_PORT;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);


        /* ctcsec IPv4, key: port + ip-da + ip-sa + ip-protocol */
        hash_sel.packet_type = CTC_DOT1AE_PKT_CTCSEC_IPV4;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_DA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_SA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_PROTOCOL;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* ctcsec IPv6, key: port + ip-da + ip-sa + ip-protocol */
        hash_sel.packet_type = CTC_DOT1AE_PKT_CTCSEC_IPV6;
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IPV6_DA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IPV6_SA;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_IP_PROTOCOL;
        hash_sel.field_cnt = key_field_id;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);


        /* ctcsec with shim header, key: SPI */
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_DOT1AE_SPI;
        hash_sel.field_cnt = key_field_id;
        hash_sel.packet_type = CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);
        hash_sel.packet_type = CTC_DOT1AE_PKT_CTCSEC_IPV6_CTCSH;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);

        /* for plain packet bypass decryption, default key: port + ethtype */
        key_field_id = 0;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_PORT;
        hash_sel.field_key_list[key_field_id++].type = CTC_FIELD_KEY_ETHER_TYPE;
        hash_sel.field_cnt = key_field_id;
        hash_sel.packet_type = CTC_DOT1AE_PKT_IPV4;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);
        hash_sel.packet_type = CTC_DOT1AE_PKT_IPV6;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);
        hash_sel.packet_type = CTC_DOT1AE_PKT_OTHERS;
        CTC_ERROR_GOTO(sys_at_dot1ae_set_hash_field_sel(lchip, &hash_sel),ret,free_mem);
    }

    CTC_ERROR_GOTO(SYS_CB_REGISTER(lchip, SYS_CB_DOT1AE_SET_HASH_TYPE, sys_at_dot1ae_set_hash_type),ret,free_mem);
    CTC_ERROR_GOTO(SYS_CB_REGISTER(lchip, SYS_CB_DOT1AE_GET_SECY_STATS, sys_at_dot1ae_get_secy_stats),ret,free_mem);
    if (lchip == SYS_PP_BASE(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_MACSEC, sys_at_dot1ae_isr_defect),ret,free_mem);
        CTC_ERROR_GOTO(sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_DOT1AE, sys_at_isr_dot1ae_process_isr),ret,free_mem);
    }
    if (DRV_FROM_AT(lchip))
    {
        uint32 value = 0;
        if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
        {
            goto free_mem;
        }
        sys_usw_ftm_get_profile_specs(lchip, CTC_FTM_SPEC_NAPT, &value);
        if (0 == value)
        {
            CTC_ERROR_RETURN(sys_usw_xdata_func_en(lchip, SYS_XDATA_FUNC_ECMP_HASH_H, 1, NULL));
        }
    }

free_mem:
 mem_free(hash_sel.field_key_list);
 return ret;

}

int32
sys_at_dot1ae_entry_hash_init(uint8 lchip)
{
    uint8 pp_num = SYS_PP_NUM(lchip);
    uint8 pp_base = drv_vchip_get_pp_base(lchip);
    uint32 entry_num = 0;
    uint32 block_size = 0;

    if (SYS_COM_ENTRY_HASH_SUPPORT_CHECK(lchip, CTC_FEATURE_DOT1AE))
    {
        return CTC_E_NONE;
    }
    if (pp_base != lchip)
    {
        usw_dot1ae_master[lchip]->entry_hash_db  = usw_dot1ae_master[pp_base]->entry_hash_db;
        return CTC_E_NONE;
    }

    entry_num = (MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM)*2)*pp_num;
    block_size = CTC_HASH_32_BLOCK_SIZE;
    usw_dot1ae_master[lchip]->entry_hash_db = sys_usw_com_entry_hash_init(lchip, entry_num, block_size);
    if(usw_dot1ae_master[lchip]->entry_hash_db == NULL)
    {
        return CTC_E_NO_MEMORY;
    }

    return CTC_E_NONE;
}

void
sys_at_dot1ae_entry_hash_deinit(uint8 lchip)
{
    if (SYS_COM_ENTRY_HASH_SUPPORT_CHECK(lchip, CTC_FEATURE_DOT1AE))
    {
        return;
    }
    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        usw_dot1ae_master[lchip]->entry_hash_db = NULL;
        return;
    }

    sys_usw_com_entry_hash_deinit(lchip, usw_dot1ae_master[lchip]->entry_hash_db);
    return;
}

#endif
#endif

